Gibt es einen Sinn für Schnittstellen in dynamischen Sprachen?

Lesezeit: 6 Minuten

Benutzer-Avatar
René Saarsoo

In statischen Sprachen wie Java braucht man Interfaces, weil man sonst mit dem Typsystem bestimmte Dinge einfach nicht machen kann. Aber in dynamischen Sprachen wie PHP und Python macht man sich das einfach zunutze Ententypisierung.

PHP unterstützt Schnittstellen. Ruby und Python haben sie nicht. Sie können also eindeutig glücklich ohne sie leben.

Ich habe meine Arbeit hauptsächlich in PHP gemacht und nie wirklich Gebrauch von der Fähigkeit gemacht, Schnittstellen zu definieren. Wenn ich eine Reihe von Klassen benötige, um eine bestimmte gemeinsame Schnittstelle zu implementieren, beschreibe ich sie einfach in der Dokumentation.

Also was denkst du? Ist es nicht besser, überhaupt auf Oberflächen in dynamischen Sprachen zu verzichten?

Ich sehe es eher als Komfortfaktor. Wenn Sie eine Funktion haben, die ein “dateiähnliches” Objekt nimmt und nur eine read()-Methode dafür aufruft, dann ist es unbequem – sogar einschränkend – den Benutzer zu zwingen, eine Art Dateischnittstelle zu implementieren. Genauso einfach lässt sich prüfen, ob das Objekt eine read-Methode hat.

Wenn Ihre Funktion jedoch eine große Anzahl von Methoden erwartet, ist es einfacher zu prüfen, ob das Objekt eine Schnittstelle unterstützt, als zu prüfen, ob jede einzelne Methode unterstützt wird.

Ja, es gibt einen Punkt

Wenn Sie Schnittstellen nicht explizit verwenden, verwendet Ihr Code das Objekt immer noch so, als ob es bestimmte Methoden implementiert hätte, es ist nur unklar, was die unausgesprochene Schnittstelle ist.

Wenn Sie eine Funktion definieren, um eine Schnittstelle zu akzeptieren (z. B. in PHP), schlägt sie früher fehl, und das Problem liegt beim Aufrufer, nicht bei der Methode, die die Arbeit erledigt. Im Allgemeinen ist es eine gute Faustregel, früher zu scheitern.

Schnittstellen fügen statischen Sprachen, die sie haben, wie Java, tatsächlich ein gewisses Maß an dynamischer, langähnlicher Flexibilität hinzu. Sie bieten eine Möglichkeit, ein Objekt abzufragen, für welche Verträge es implementiert zur Laufzeit.

Dieses Konzept lässt sich gut in dynamische Sprachen übertragen. Abhängig von Ihrer Definition des Wortes “dynamisch” schließt das natürlich sogar Objective-C ein, das in Cocoa ziemlich ausführlich von Protokollen Gebrauch macht.

In Ruby können Sie fragen, ob ein Objekt auf einen bestimmten Methodennamen reagiert. Aber das ist eine ziemlich schwache Garantie dafür, dass es das tut, was Sie wollen, insbesondere wenn man bedenkt, wie wenige Wörter immer wieder verwendet werden, dass die vollständige Methodensignatur nicht berücksichtigt wird usw.

In Ruby könnte ich fragen

object.respond_to? :sync

Also, ja, es hat eine Methode namens “sync”, was auch immer das bedeutet.

In Objective-C könnte ich etwas Ähnliches fragen, dh “sieht / geht / quakt das aus wie etwas, das synchronisiert wird?”:

[myObject respondsToSelector:@selector(sync)]

Noch besser, auf Kosten einiger Ausführlichkeit kann ich etwas Spezifischeres fragen, dh “sieht/geht/quakt das wie etwas, das mit MobileMe synchronisiert wird?”:

[myObject respondsToSelector:@selector(sync:withMobileMeAccount:)]

Das ist Ententypisierung bis auf die Artebene.

Aber ein Objekt wirklich zu fragen, ob es erfolgversprechend ist, eine Synchronisation zu MobileMe zu implementieren…

[receiver conformsToProtocol:@protocol(MobileMeSynchronization)]

Natürlich könnten Sie Protokolle implementieren, indem Sie einfach prüfen, ob eine Reihe von Selektoren vorhanden sind, die Sie als Definition eines Protokolls / einer Ente betrachten, und ob sie spezifisch genug sind. An welchem ​​Punkt ist das Protokoll nur noch eine Abkürzung für einen Haufen hässlicher Responses_to? Abfragen und einigen sehr nützlichen syntaktischen Zucker für den Compiler/die zu verwendende IDE.

Schnittstellen/Protokolle sind eine weitere Dimension von Objektmetadaten, die verwendet werden können, um dynamisches Verhalten bei der Handhabung dieser Objekte zu implementieren. In Java verlangt der Compiler so etwas für den normalen Methodenaufruf. Aber selbst dynamische Sprachen wie Ruby, Python, Perl usw. implementieren einen Typbegriff, der über „auf welche Methoden ein Objekt antwortet“ hinausgeht. Daher das Schlüsselwort class. Javascript ist die einzige wirklich gebräuchliche Sprache ohne dieses Konzept. Wenn Sie Klassen haben, dann machen auch Schnittstellen Sinn.

Es ist zugegebenermaßen nützlicher für kompliziertere Bibliotheken oder Klassenhierarchien als in den meisten Anwendungscodes, aber ich denke, das Konzept ist in jeder Sprache nützlich.

Außerdem erwähnte jemand anderes Mixins. Ruby-Mixins sind eine Möglichkeit, Code gemeinsam zu nutzen – zB beziehen sie sich auf die Implementierung einer Klasse. Bei Schnittstellen/Protokollen handelt es sich um die Schnittstelle einer Klasse oder eines Objekts. Sie können sich tatsächlich ergänzen. Möglicherweise haben Sie eine Schnittstelle, die ein Verhalten angibt, und ein oder mehrere Mixins, die einem Objekt dabei helfen implementieren dieses Verhalten.

Natürlich fallen mir keine Sprachen ein, die wirklich beides als unterschiedliche erstklassige Sprachmerkmale haben. Bei denen mit Mixins impliziert das Einschließen des Mixins normalerweise die Schnittstelle, die es implementiert.

Wenn Sie keine hohen Sicherheitsbeschränkungen haben (damit niemand auf Ihre Daten auf eine Weise zugreift, die Sie nicht möchten) und Sie über eine gute Dokumentation oder gut ausgebildete Programmierer verfügen (damit sie den Interpreter / Compiler nicht benötigen, um ihnen zu sagen, was sie tun sollen tun), dann nein, es ist nutzlos.

Für die meisten mittelgroßen Projekte ist Enteneingabe alles, was Sie brauchen.

Ich hatte den Eindruck, dass Python hat keine Schnittstellen. Soweit mir bekannt ist, können Sie in Python nicht erzwingen, dass eine Methode zur Kompilierungszeit implementiert wird, gerade weil es sich um eine dynamische Sprache handelt.

Es gibt Schnittstellenbibliotheken für Python, aber ich habe keine davon verwendet.

Python hat auch Mixins, so dass Sie eine Interface-Klasse erstellen könnten, indem Sie ein Mixin definieren und haben pass für jede Methodenimplementierung, aber das gibt Ihnen nicht wirklich viel Wert.

  • Vielen Dank für den Hinweis, ich habe zuvor eine Websuche durchgeführt, einen Artikel gefunden, in dem Schnittstellen in Python erörtert wurden, und bin zu dem Schluss gekommen, dass Python Schnittstellen haben muss – eigentlich hat der Artikel die Frage des Hinzufügens von Schnittstellen zu Python behandelt.

    – René Saarsoo

    18. September 2008 um 11:21 Uhr

Benutzer-Avatar
marijne

Ich denke, die Verwendung von Schnittstellen wird eher davon bestimmt, wie viele Personen Ihre Bibliothek verwenden werden. Wenn es nur Sie oder ein kleines Team sind, sind Dokumentation und Konvention in Ordnung, und das Erfordernis von Schnittstellen ist ein Hindernis. Wenn es sich um eine öffentliche Bibliothek handelt, sind Schnittstellen viel nützlicher, da sie die Menschen dazu zwingen, die richtigen Methoden bereitzustellen, anstatt nur Hinweise zu geben. Schnittstellen sind also definitiv ein wertvolles Feature für das Schreiben öffentlicher Bibliotheken, und ich nehme an, dass Mangel (oder zumindest De-Emphasis) einer der vielen Gründe ist, warum dynamische Sprachen eher für Apps und stark typisierte Sprachen für große Bibliotheken verwendet werden.

  • Vielen Dank für den Hinweis, ich habe zuvor eine Websuche durchgeführt, einen Artikel gefunden, in dem Schnittstellen in Python erörtert wurden, und bin zu dem Schluss gekommen, dass Python Schnittstellen haben muss – eigentlich hat der Artikel die Frage des Hinzufügens von Schnittstellen zu Python behandelt.

    – René Saarsoo

    18. September 2008 um 11:21 Uhr

Benutzer-Avatar
Gemeinschaft

Rene, bitte lies meine Antwort auf die Frage „Best Practices for Architecting Large Systems in a Dynamic Language“ hier auf StackOverflow. Ich diskutiere einige Vorteile, die es mit sich bringt, die Freiheit dynamischer Sprachen aufzugeben, um Entwicklungsaufwand zu sparen und neue Programmierer leichter in das Projekt einzuführen. Richtig eingesetzte Schnittstellen tragen wesentlich zum Schreiben zuverlässiger Software bei.

1062700cookie-checkGibt es einen Sinn für Schnittstellen in dynamischen Sprachen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy