2010-08-25 11 views
7

Ich arbeite in PHP, und das Konzept der Schnittstellen scheint mir ein wenig nutzlos hier. Aus dem Lesen verstehe ich, dass Schnittstellen Teil von "Design by Contract" sind, aber ohne zumindest eine Rückkehr eines Typs einer bestimmten Art zu garantieren, gibt es wirklich keinen Vertrag. Es scheint, als wäre es ein Vertrag, der lautet: "Wir stimmen zu, Folgendes zu tun: ''" - Es gibt keine Bedingungen der Vereinbarung.Warum Interfaces in dynamischen/locker typisierten Sprachen?

Wenn ich eine Garantie haben möchte, dass ein Objekt eine Methode hat, scheint es nicht so, dass Schnittstellen besonders nützlich sind. Wenn ich versuche, eine Methode aufzurufen, die ein Objekt nicht hat, bekomme ich einen Fatalen Fehler, also finde ich ziemlich schnell heraus, dass diese Klasse keine Methode mit diesem Namen hat. Wenn ich klug sein und vorher prüfen möchte, ob eine Klasse eine Methode hat, dann überprüft die Schnittstelle, und zu sehen, ob das Objekt diese Schnittstelle implementiert, scheint mir nicht mehr Zeit zu sparen, als nur dieses Objekt direkt zu überprüfen (was ich tun würde) jedenfalls um zu sehen, ob die Klasse diese Methode hatte, ungeachtet der Schnittstellen, die sie implementiert hat oder nicht implementiert hat.

Mit anderen Worten, nur weil ich eine Reihe von Methoden, die bestimmte Namen haben, das garantiert mir keine bestimmte Verhalten. Wenn ich eine Rückgabe einer Variablen eines bestimmten Typs garantiere, habe ich zumindest eine Ahnung davon, was die Ausgabe sein würde, und ich kann Code schreiben, der ein Objekt mit dieser Schnittstelle verwendet, weil ich weiß, was ich herausbekomme davon. Wenn es eine Zeichenkette zurückgibt, kann ich weiter mit mindestens der Gewissheit kodieren, dass ich nachher mit einer Zeichenkettenausgabe handle. So ist mir zumindest ein gewisses Verhalten garantiert, wenn ein Rückgabetyp angegeben ist. Garantiert das Verhalten Teil der Schnittstellen oder nicht?

Das einzige, was mir einfällt, ist, dass wenn ich Code schreibe, es als eine Post-it-Notiz für mich dient, um bestimmte Methoden zu erstellen, wenn ich diese Klasse später schreibe. Es scheint mehr wie ein Gerüst zu sein, wenn ich den Code schreibe; Ich sehe keinen großen Nutzen daraus, wenn ich es tatsächlich benutze. Es ist also mehr für mich, beim Erstellen von Klassen den Standard einzuhalten, als wenn ich sie schreibe. Dieser Vorteil scheint im Konzept des Vertragsdesigns nicht wirklich berücksichtigt zu werden.

Welchen Nutzen (n) haben Sie eigentlich von der Verwendung einer Schnittstelle in dynamischen/losen Sprachen wie PHP? Sind sie großartig oder ist es etwas, das robustere OO-Sprachen implementieren, also implementiert PHP es auch?

+4

Pedantische Anmerkung: PHP ist nicht 'Untyped'. Es ist dynamisch und locker typisiert. Es gibt einen RIESIGEN Unterschied ... – ircmaxell

+0

Das ist nicht so pedantisch, wenn es einen großen Unterschied macht :) Fixed. – user151841

+1

Was ist, wenn Ihre Software erfordert, dass eine Methode eine Primzahl oder eine US-ASCII-Zeichenfolge zurückgibt? Nur weil eine Schnittstelle diesen Teil des "Vertrags" nicht spezifizieren kann und diese Dinge Ihr Programm abwerfen können, bedeutet das, dass Schnittstellen in allen Sprachen völlig nutzlos sind? Auch in stark typisierten Sprachen erzeugt ein Typ-Mismatch einen Fehler. Sie könnten also genauso leicht fragen, warum Sie in stark typisierten Sprachen einen Rückgabetyp in Ihrer Oberfläche angeben müssen. –

Antwort

3

Schnittstellen werden verwendet, wenn Sie tatsächlich erwarten, dass ein Objekt eine Methode implementiert.

Zum Beispiel, wenn ich einen DB-Wrapper erstellen und es Verhaltensweisen unterstützt, die Sie selbst in einem Bootstrap registrieren, dann bevor ich Ihr Verhalten (z. B. träge), werde ich überprüfen, dass sie meine "DB_Wrapper_Behaviour_Interface" implementieren mit:

if(!($behaviourObject instanceof DB_Wrapper_Behaviour_Interface)) { 
    throw new Exception("Your behaviour doesn't implement my interface"); 
} 
+0

user151841 hat diesen Aspekt bereits in der Frage ausgewählt. Können Sie bitte den Nutzen der in der Frage aufgeworfenen Zweifel näher erläutern? – VolkerK

+0

Mehr als nur eine 'Methode'. Eine Methodensignatur. Einschließlich Typen Hinweise und Standardeinstellungen ... – ircmaxell

+0

VolkerK, sowohl von OP als auch von greg0ire Ich habe das Gefühl, dass sie Interfaces für Ein-Mann-Projekte verwenden. Während dies unterstützt wird, werden Schnittstellen sinnvoller, wenn Inter-Entwickler-Annahmen ins Spiel kommen, wie mein DB Wrapper - Verhaltensbeispiel. –

0

Ein fataler Fehler ist nicht immer "einfach". Manchmal müssen Sie auf ein bestimmtes Modul/eine Aktion gehen, um zu sehen, dass in Ihrer Klasse etwas fehlt. Die Schnittstelle ermöglicht es Ihnen sicherzustellen, dass jede Methode implementiert ist und diese Methode zu dokumentieren (was die Parameter genau sein werden, wie die Rückgabewerte aussehen sollten). Dies ist nützlich, wenn die Parameter/Werte Arrays mit einer bestimmten Struktur sind und Sie stattdessen keine Klassen verwenden möchten (der Einfachheit halber).

+0

"Wie die Rückgabewerte aussehen sollten" - aber das wird von php nicht erzwungen (und user151841 hat das aufgegriffen Aspekt auch in der Frage). Also "zu dokumentieren" ist wörtlich zu nehmen; Externe Tools und/oder IDE können diese zusätzliche Information/Anmerkung aufnehmen, aber PHP selbst ist nicht wichtig. – VolkerK

+0

@ greg0ire Ich kenne viele andere Sprachen nicht. Können Sie in PHP ein Beispiel geben, wo Sie eine nicht existierende Methode für eine Eigenschaft aufrufen, und es ist unklar, was genau falsch gelaufen ist? – user151841

+0

@ user151841: Nein, ich kann nicht, warum würde versuchen, so etwas zu tun? Was ich sagte, ist, dass es schwieriger ist sicherzustellen, dass jede Methode, die Sie implementieren sollen, implementiert wird, wenn es keine Schnittstelle gibt. Sie müssen den gesamten Code der Anwendung nach Aufrufen der Getter der Eigenschaft durchsuchen und dann sehen, welche Methoden aufgerufen werden. Unit-Tests all Ihrer App können Ihnen helfen, schwerwiegende Fehler zu finden, aber eine Schnittstelle ist viel bequemer. – greg0ire

0

Ich möchte darauf hinweisen, dass PHP 5.4 Type Hinting unterstützt. Momentan denke ich, dass es nur Typhinweis für Funktionsargumente gibt, aber ich nehme an, dass es auch für Rückgabewerte geben wird. (Wenigstens gibt es bereits eine RFC, obwohl eine sehr alte und veraltete.)

+0

Es ist da, aber es ist immer noch ein [sehr umstrittenes Feature] (http://schlueters.de/blog/archives/139-Scalar-type-hints-in-PHP-trunk.html) ... Ich bin nicht drin Unterstützung der aktuellen Implementierung ... Ich denke, es ist zu strikt, um nutzbar zu sein. – ircmaxell

+0

hm, ich kann dort nichts über Rückgabewert Typ Hinweise finden ... – NikiC

+0

Ich meinte für Argument Typ Hinting. Ich habe nichts über Rückgabetypen gehört ... Sorry für die Verwirrung ... – ircmaxell

1

Design durch Vertrag wird schwieriger gemacht, ohne Rückgabetypen, aber vergessen Sie nicht zu bevorzugen 'sagen' über 'fragen'.

Ich glaube eine Schnittstelle, um etwas wie eine Verantwortung zu sein. Sie programmieren und brauchen einen Mitarbeiter. Sie bitten es, etwas zu tun, weil der Code, an dem Sie arbeiten, nicht alles kann. Sie bitten also ein anderes Objekt, etwas zu tun. Eine Schnittstelle garantiert, dass der Kollaborateur die Aufgabe erledigt, verbirgt aber das "Wie".

Nun könnte man argumentieren, dass hier kein formeller Vertrag benötigt wird, da das System sowieso einen Fehler ausgibt, wenn der Kollaborateur nicht das tun kann, was er verlangt. Aber ich denke, das vermisst die Verwendung von Schnittstellen als eine Verantwortung.