Wann sollten Interfaces in Dart verwendet werden?

8

Ich habe Dart's Dokumentation gelesen und war ein wenig verwirrt, vielleicht weil ich von Ruby komme, um Interfaces zu benutzen. Natürlich sind Schnittstellen für Dart nicht einzigartig und es gibt eine ganze Reihe von Erklärungen darüber, wann man eine Schnittstelle verwenden sollte. Dieser zum Beispiel scheint zu sagen, dass Interfaces nur nützlich sind, wenn Sie in einem Team. Was soll das überhaupt in der Open-Source-Welt bedeuten, wo jeder den Code von jemand anderem liest und wieder verwendet?

Eine interessante Erklärung, die ich gesehen habe, scheint zu sein, dass Schnittstellen verwendet werden:

  1. in Sprachen ohne Mehrfachvererbung und
  2. In diesem Fall dienen sie irgendwie als Workaround für das Fehlen der Mehrfachvererbung.

Ich verstehe das nicht. Ich verstehe, dass Module in Ruby ein Workaround sind, weil sie mir erlauben, echte Methoden mit tatsächlichen Körpern zu definieren. Schnittstellen erlauben mir nur zu definieren, welche Methoden eine Klasse implementieren sollte. Was ist der Haken? Kann jemand von einem wirklich nützlichen Beispiel erzählen, in dem ich den Wert der Verwendung von Schnittstellen sofort sehen kann?

P.S. Gibt es eine Möglichkeit, Mehrfachvererbung in Dart zu verwenden?

    
snitko 08.05.2012, 16:33
quelle

3 Antworten

19

Schnittstellen sind nützlich, da sie es Ihnen ermöglichen, Implementierungen einer Klasse zu wechseln, während Sie weiterhin die Validierung zulassen, dass der übergebene Typ die Anforderungen der Schnittstelle erfüllt.

Nehmen Sie das folgende (häufig verwendete) Beispiel:

%Vor%

Dies definiert die Anforderungen einer Klasse, die an eine Methode wie folgt übergeben wird:

%Vor%

ermöglicht es Ihnen, jede Implementierung eines Quackable-Objekts zu verwenden, z. B .:

%Vor%

Beide Implementierungen funktionieren mit der Funktion sayQuack (), aber eine benötigt wesentlich weniger Infrastruktur als die andere.

%Vor%

Ich benutze dieses Muster die ganze Zeit in der Java-Welt, wenn ich Lösungen entwickle, die eine "Enterprise-Ente" verwenden. Wenn ich lokal arbeite, muss ich nur die Funktion sayQuack () aufrufen und einige fest codierte Mock-Daten zurückgeben.

Ente tippen

Da Dart optional typisiert ist, müssen Sie die Schnittstelle nicht wirklich verwenden, sondern einfach eine Klasse schreiben, die die korrekte Methodensignatur enthält (obwohl die Werkzeuge diese nicht validieren können).

%Vor%

Alle Klassen sind Schnittstellen

Schließlich sind alle Klassen auch Schnittstellen. Dies bedeutet, dass obwohl ein Drittanbietersystem ohne Verwendung von Schnittstellen geschrieben wurde, Sie trotzdem eine konkrete Klasse als Schnittstelle verwenden können.

Stellen Sie sich beispielsweise die folgende Enterprise-Bibliothek vor:

%Vor%

Und Sie möchten eine simulierte Ente in die sayQuack-Methode auf eine Weise übergeben, die der Typüberprüfer überprüfen kann. Sie können Ihren mockDuck erstellen, um die von EnterpriseDuck implizierte Schnittstelle zu implementieren, indem Sie einfach den EnterpriseDuck als Schnittstelle verwenden:

%Vor%

Mehrfachvererbung

Im Hinblick auf Mehrfachvererbung ist dies in Dart nicht möglich. Sie können jedoch mehrere Schnittstellen implementieren und eigene Implementierungen der erforderlichen Methoden bereitstellen, z. B .:

%Vor%

Schnittstellen können Standardklassen haben

Wenn Sie Dart verwenden, werden Sie feststellen, dass die meisten "Klassen" tatsächlich Schnittstellen sind. Liste, String etc ... sind alle Schnittstellen mit den bereitgestellten Standardimplementierungen. Wenn Sie

anrufen %Vor%

Sie verwenden tatsächlich eine List-Schnittstelle und das neue Schlüsselwort leitet von der Schnittstelle zu einer zugrunde liegenden Standard-List-Implementierung um.

In Bezug auf die Entwicklung in einem Team

Schnittstellen sind in der Teamentwicklung nützlich, auch in der Open-Source-Welt. Die Schnittstelle definiert die Methoden und Eigenschaften, die Sie erstellen sollten, damit Ihre Komponente mit meiner Komponente funktioniert. Sie können Ihre eigene Testimplementierung dieser Schnittstelle erstellen und ich kann meine konkrete Implementierung dieser Schnittstelle erstellen, und wenn wir fertig sind, können wir sie integrieren. Ohne die veröffentlichte, gemeinsam genutzte Schnittstelle müsste ich meine konkrete Implementierung bereitstellen, bevor Sie wirklich anfangen könnten.

Hoffe das hilft!

    
Chris Buckett 08.05.2012, 19:24
quelle
4

Grundsätzlich haben Schnittstellen nichts mit Mehrfachvererbung zu tun. Es ist zwar möglich, mehrere Vererbungs- und Missbrauchsschnittstellen zu fälschen, aber wenn Sie echte Mehrfachvererbung (oder Mixins oder Merkmale) wollen, stellt Dart sie nicht zur Verfügung (derzeit - ich glaube, dass Mixins irgendwann ihren Weg finden werden) ).

Wofür Schnittstellen gut sind, ist expliziter Vertrag . Angenommen, Sie haben zwei Komponenten A und B , die miteinander arbeiten müssen. Sie können sicher B von A direkt aufrufen und es wird funktionieren, aber das nächste Mal, wenn Sie B ändern wollen, müssen Sie sich A ansehen, wie es es benutzt. Das liegt daran, dass B keine explizite Schnittstelle verfügbar gemacht hat . Ja, das richtige Wort für Interfaces ist nicht implementieren , sondern expose .

Wenn Sie die Implementierung von B hinter einer Schnittstelle verstecken und diese Schnittstelle nur A zur Verfügung stellen, können Sie B nach Belieben ändern und sich nur darum sorgen, dass immer noch dieselbe Schnittstelle anzeigt . Die Schnittstelle kann sogar von mehr als einer Klasse offen gelegt werden, und der Anrufer muss sich nicht darum kümmern (oder auch nicht wissen).

Beachten Sie, dass das Wort Schnittstelle hier zwei Bedeutungen hat: den allgemeinen Vertrag der Komponente, der in der Dokumentation auch einfach in Englisch beschrieben werden kann, und ein spezielles Sprachkonstrukt , das Ihnen hilft, einige Teile des Vertrags direkt in der Programmiersprache zu beschreiben (und auch zu erzwingen).

Sie müssen nicht unbedingt das Sprachkonstrukt verwenden, aber es wird als guter Stil angesehen, es zu verwenden, um die Teile des Vertrags zu beschreiben, die die Programmiersprache Ihnen erlaubt.

Nun, was zum Teufel ist ein Vertrag hier? Kurz gesagt, contract ist eine Beschreibung von , was die Komponente von ihrem Benutzer erwartet und was der Benutzer von der Komponente erwarten kann.

Nehmen wir zum Beispiel an, ich habe eine Methode, die den absoluten Wert einer Zahl berechnet:

%Vor%

Der Vertrag hier ist vollständig im Dokumentationskommentar beschrieben (na ja, nicht ganz, wir könnten auch beschreiben, was der absolute Wert ist, aber das ist gut genug). Nun ... aber einige Teile des Kommentars können direkt in der Sprache ausgedrückt werden, oder?

%Vor%

Beachten Sie, dass einige Teile des Vertrages einfach nicht in der Programmiersprache ausgedrückt werden können - hier hat die Sprache keine Ahnung was absoluter Wert ist, dies braucht im Kommentar bleiben. Außerdem können Sie nicht ausdrücken, dass der Rückgabewert niemals negativ ist, also muss dies auch im Kommentar bleiben. Aber tatsächlich wissen die Leser Ihres Codes was ein absoluter Wert ist (und dass er niemals negativ ist) und der Methodenname ist ziemlich klar über den Zweck, so dass der Kommentar vollständig weggelassen werden kann:

%Vor%

Nun werden einige Teile des Vertrags explizit ausgedrückt, wobei die Sprachmittel verwendet werden, und einige Teile werden implizit ausgedrückt (Sie verlassen sich darauf, dass die Leute wissen, was der absolute Wert ist).

Und Schnittstellen in der Sprache werden verwendet, um den Vertrag von der Implementierung zu entkoppeln . Es ist wahrscheinlich zu viel Aufwand in kleinen Programmen zu verwenden, aber es zahlt sich aus, wenn größere Programme gemacht werden (die nicht Teamarbeit erfordern).

Uff, das war länger als ich erwartet hatte. Hoffe das hilft.

    
Ladicek 09.05.2012 07:13
quelle
1

Schnittstellen sind Teil des Typsystems in Dart und Typdeklarationen sind optional. Dies bedeutet, dass Schnittstellen auch optional sind.

Mit

Interfaces können Sie die Methoden dokumentieren, auf die Ihr Objekt reagiert. Wenn Sie die Schnittstelle implementieren, dann versprechen Sie, alle Methoden in der Schnittstelle zu implementieren.

Dart verwendet diese Informationen, um Kompilierungswarnungen von Typenkonflikten anzuzeigen, um hilfreichere Vorschläge für die Codeunterstützung bereitzustellen und bei einigen Refactorings zu helfen.

    
David Buck 08.05.2012 16:42
quelle

Tags und Links