In Rich Hickeys zum Nachdenken anregendem Hauptvortrag " The Value of Values " (29 Minuten) spricht er über den Overhead einer Sprache wie Java und erklärt: "Alle diese Schnittstellen töten Ihre Wiederverwendung." Was meint er? Ist das wahr?
Auf meiner Suche nach Antworten bin ich auf folgendes gestoßen:
Das Prinzip des geringsten Wissens AKA Das Gesetz von Demeter, das luftdichte API-Schnittstellen fördert. Wikipedia listet auch einige Nachteile auf.
Kevlin Henneys Imperial Clothing Crisis, die argumentiert, dass die Verwendung, nicht die Wiederverwendung, das angemessene Ziel ist.
Jack Diederichs " Stop Writing Classes " -Rede spricht sich generell gegen Überentwicklung aus.
Offensichtlich ist alles, was schlecht genug geschrieben wurde, nutzlos. Aber wie würde die Schnittstelle einer gut geschriebenen API verhindern, dass dieser Code verwendet wird? Es gibt in der Geschichte Beispiele dafür, dass etwas, das für einen bestimmten Zweck gemacht wurde, mehr für etwas anderes verwendet wird . Aber in der Softwarewelt bricht es normalerweise zusammen, wenn Sie etwas für einen Zweck verwenden, für den es nicht vorgesehen war.
Ich suche ein gutes Beispiel für eine gute Schnittstelle, die eine legitime, aber unbeabsichtigte Verwendung von Code verhindert. Existiert das? Ich kann es mir nicht vorstellen.
quelle
Antworten:
Ich habe die vollständige Präsentation von Rich Hickey noch nicht gesehen, aber wenn ich ihn richtig verstehe und nach seinen Aussagen zur 29-Minuten-Marke urteile, scheint er über Typen zu streiten , die die Wiederverwendung töten. Er verwendet den Begriff "Schnittstelle" lose als Synonym für "benannten Typ", was Sinn macht.
Wenn Sie zwei Entitäten
{ "name":"John" }
vom TypPerson
und{ "name": "Rover" }
vom TypDog
in Java-Land haben, können sie wahrscheinlich nicht zusammenarbeiten, es sei denn, sie teilen sich eine gemeinsame Schnittstelle oder einen gemeinsamen Vorfahren (wie z. B.Mammal
das Schreiben von mehr Code). So die Schnittstellen / hier Typen sind „Tötung Ihre Wiederverwendung“: obwohlPerson
undDog
gleich aussehen, kann man nicht austauschbar mit anderen verwendet werden, es sei denn , Sie zusätzlichen Code schreiben, zu unterstützen. Hinweis: Hickey macht auch Witze über Projekte in Java, die viele Klassen benötigen ("Wer hat hier eine Java-Anwendung mit nur 20 Klassen geschrieben?"), Was eine Konsequenz des oben Gesagten zu sein scheint.In "wertorientierten" Sprachen weisen Sie diesen Strukturen jedoch keine Typen zu. Es handelt sich nur um Werte, die zufällig dieselbe Struktur haben (in meinem Beispiel haben beide ein
name
Feld mit einem String-Wert) und können daher problemlos zusammenarbeiten, z. B. können sie derselben Sammlung hinzugefügt, denselben Methoden übergeben usw. werden.Zusammenfassend scheint dies alles etwas über strukturelle Gleichheit im Vergleich zu expliziter Typ / Schnittstellen-Gleichheit zu sein . Es sei denn, ich habe etwas aus den Teilen des Videos verpasst, die ich noch nicht gesehen habe :)
quelle
ERROR: Object doesn't have a property called "name"
ist oft das Ergebnis vonvalue-oriented
Sprachen, und das andere Problem ist, wenn Sie diese Eigenschaft nicht mehr aufrufen möchtenname
. Viel Glück beim Refactoring, denn es gibt wahrscheinlich Hunderte von Objekten mit einer Immobilie,name
aber nicht alle sindPerson
oderDog
.interface
s zu tun, sondern mit dem Durcheinander, das ein typisches Java-Projekt ist.Er bezieht sich wahrscheinlich auf die grundlegende Tatsache, dass eine Schnittstelle nicht instanziiert werden kann. Sie können keine
reuse
Schnittstelle. Sie können nur Code implementieren, der dies unterstützt, und wenn Sie Code für eine Schnittstelle schreiben, erfolgt keine erneute Verwendung.Java hat in der Vergangenheit Frameworks für viele APIs bereitgestellt, die eine Schnittstelle als Argumente verwenden. Das Team, das die API entwickelt hat, implementiert jedoch niemals eine Vielzahl von Klassen, die Sie mit diesen Schnittstellen wiederverwenden können.
Es ist wie ein GUI-Framework, das eine
IWindow
Schnittstelle für ein Dialogfeld hat, und dann können SieIButton
Schnittstellen für Steuerelemente hinzufügen . Außer, sie haben dir nie eine guteButton
Klasse gegeben, die implementiertIButton
. Sie müssen also Ihre eigenen erstellen.Abstrahierte Frameworks mit einer Vielzahl von Basisklassen, die Kernfunktionalitäten bereitstellen, sind wiederverwendbarer und funktionieren am besten, wenn diese abstrahierten Klassen für Benutzer des Frameworks zugänglich sind.
Java-Entwickler haben damit begonnen, dass ihre API-Ebenen nur verfügbar gemacht wurden
interfaces
. Sie könnten diese Schnittstellen implementieren, aber Sie könnten niemals Klassen des Entwicklers wiederverwenden, der diese Schnittstellen implementiert hat. Es ist eine Art Umhang und Dolch für die API-Entwicklung.quelle
Ich denke, Folie 13 bei seiner Präsentation ( Der Wert der Werte ) hilft, dies zu verstehen:
Nach meinem Verständnis schlägt Hickey vor, dass ich, wenn ich beispielsweise den Wert, den Sie mir gesendet haben , verdoppeln muss, einfach Code schreibe, der so aussieht
Sie sehen, obiger Code ist derselbe, egal welchen Wert Sie gesendet haben - eine Art perfekte Wiederverwendung .
Wie würde dies nun in der Sprache mit Objekten und Schnittstellen aussehen?
Oh, Moment mal! Was ist, wenn
YourValue
nicht implementiertDoublable
? nicht, dass es nicht verdoppelt werden kann, es mag perfekt sein, aber ... was ist, wenn es nur keine Methode gibtDouble
? (Was ist, wenn es eine Methode namens say gibtTwiceAsMuch
?)Oh, wir haben ein Problem.
YourValue.Double
funktioniert nicht mehr , kann nicht mehr wiederverwendet werden. Nach meiner Lektüre der obigen Folie hat Hickey damit gemeint: "All diese Schnittstellen töten Ihre Wiederverwendung!"Sie sehen, Interfaces setzen voraus, dass Objekte "zusammen mit ihren Methoden" und Code, der mit diesen arbeitet, weitergegeben werden. Um Objekte zu verwenden, muss man wissen, wie man diesen Code aufruft und welche Methode man aufruft .
Wenn die erwartete Methode fehlt, liegt ein Problem vor, obwohl die gewünschte Operation semantisch für ein Objekt durchaus sinnvoll ist. Wie in der Präsentation angegeben, benötigen Werte keine Methoden ("Ich kann Ihnen Werte ohne Code senden, und es geht Ihnen gut"), sodass Sie Code schreiben können, der sich allgemein mit ihnen befasst.
Randnotiz: Der Gedanke, codelose Werte weiterzugeben, erinnert mich irgendwie an ein Flyweight-Muster in OOP.
Ich habe gesehen, dass die Verwendung von Fliegengewichten in der Regel denselben Ansatz verfolgt, bei dem der Code (Methoden, Schnittstellen) von Objekten gestrippt und Dinge herumgereicht wurden, und zwar auch Werte ohne Code.
Das fühlt sich ziemlich ähnlich an wie auf der Folie: "Werte brauchen keine Methoden. Ich kann Ihnen Werte ohne Code senden und es geht Ihnen gut."
quelle
MyValue = Double(YourValue)
ist nicht sinnvoll, wenn YourValue eine Zeichenfolge, eine Adresse, ein Benutzer, eine Funktion oder eine Datenbank ist. Andernfalls ist das Argument für die fehlende Methode stark. Mit den OTOH-Zugriffsmethoden können Sie verschiedene Einschränkungen erzwingen, sodass Ihre Werte gültig sind und nur sinnvolle Operationen zum Erstellen neuer Werte verwendet werden. Wenn Sie sich später dazu entschließen, die Adresse von Ihrem Benutzer und Ihrer Firma zu trennen, führen Accessormethoden dazu, dass Sie nicht alle Clients Ihres Codes auflösen. So können sie langfristig zur Wiederverwendung beitragen, auch wenn sie diese manchmal kurzfristig behindern.In einer (dh meiner) idealen Welt beschreiben Klassen und Schnittstellen immer das Verhalten, aber Tatsache ist, dass sie allzu oft wirklich nur Daten beschreiben. Erst gestern habe ich mir ein Video von jemandem angeschaut, der eine sogenannte
BankAccount
Klasse gebaut hat, die nichts weiter als eine verherrlichte Klasse warint
(in der Tat war es viel weniger nützlich als eineint
, also die Wiederverwendung "töten", die ich gehabt hätte, wenn sie einfach als eine verlassen worden wäreint
). Alles im Namen von "gutem" Design. Die Menge an Code, Schweiß und Tränen, die verschwendet wird, um verschlungene Darstellungen von Daten immer wieder neu zu erfinden, ist erstaunlich. Wenn Sie die Daten nicht sinnvoll verwenden, lassen Sie es bitte einfach sein.Nun, dies ist die Phase, in der Rich Hickey damit zufrieden ist, das Baby mit dem Badewasser hinauszuwerfen und zu sagen, dass wir alle im Land der Werte (einem Nachbarn des Reiches der Nomen) leben sollen. Ich denke andererseits, dass OOP die Wiederverwendung (und vor allem die Auffindbarkeit, die mir bei der funktionalen Programmierung fehlt) fördern kann und tut, wenn es mit Bedacht eingesetzt wird. Wenn Sie nach einem OOP-Prinzip suchen, das diese Spannung am besten aufnimmt, dann könnte es http://c2.com/cgi/wiki?TellDontAsk sein (was natürlich ein enger Verwandter von Demeter ist).
quelle