In diesem Video von Rich Hickey , dem Entwickler von Clojure, rät er dazu, Map zur Darstellung von Daten zu verwenden, anstatt eine Klasse zur Darstellung zu verwenden, wie dies in Java geschieht. Ich verstehe nicht, wie es besser sein kann, da wie der API-Benutzer wissen kann, was die Eingabetasten sind, wenn sie einfach als Karten dargestellt werden.
Beispiel :
PersonAPI {
Person addPerson(Person obj);
Map<String, Object> addPerson(Map<String, Object> personMap);
}
In der zweiten Funktion, wie kann der API-Benutzer wissen, welche Eingaben erforderlich sind, um eine Person zu erstellen?
Antworten:
Exagg'itive Summary (TM)
Sie bekommen ein paar Dinge.
Es gibt einen fatalen Nachteil.
Die Sache ist, Sie können Introspektion erhalten, indem Sie, ähm, Introspektion verwenden. Das ist was normalerweise passiert:
Mit anderen Worten, wenn Sie nie eine Schnittstelle zu FP benötigen, müssen Sie Rich Hickeys Rat nicht befolgen.
Last but not least (oder am schönsten), obwohl die Verwendung
String
als Eigenschaftsschlüssel am einfachsten ist, müssen Sie nichtString
s verwenden. Viele ältere Systeme, einschließlich Android ™, verwenden im gesamten Framework ausführlich Ganzzahl-IDs, um auf Klassen, Eigenschaften, Ressourcen usw. zu verweisen.Android ist eine Marke von Google Inc.
Sie können auch beide Welten glücklich machen.
Implementieren Sie für die Java-Welt die Getter und Setter wie gewohnt.
Implementieren Sie für die FP-Welt die
Object getPropertyByName(String name)
void setPropertyByName(String name, Object value) throws IllegalPropertyChangeException
List<String> getPropertyNames()
Class<?> getPropertyValueClass(String name)
Innerhalb dieser Funktion, ja, hässlicher Code, aber es gibt IDE-Plugins, die das für Sie auffüllen, mit ... äh, einem intelligenten Plugin, das Ihren Code liest .
Die Java-Seite der Dinge wird genauso performant sein wie üblich. Sie werden diesen hässlichen Teil des Codes niemals verwenden . Vielleicht möchten Sie es sogar vor Javadoc verstecken.
Die FP-Seite der Welt kann jeden "leet" -Code schreiben, den sie wollen, und sie schreien Sie normalerweise nicht an, dass der Code langsam ist.
Im Allgemeinen ist die Verwendung einer Karte (Eigentumstasche) anstelle eines Objekts in der Softwareentwicklung üblich. Dies gilt nicht nur für die funktionale Programmierung oder bestimmte Arten von Sprachen. Es mag kein idiomatischer Ansatz für eine bestimmte Sprache sein, aber es gibt Situationen, die dies erfordern.
Insbesondere die Serialisierung / Deserialisierung erfordert oft eine ähnliche Technik.
Nur ein paar allgemeine Gedanken zu "Karte als Objekt".
quelle
commonplace
scheint mir ein wenig stark zu sein. Ich meine, es wird so verwendet, wie Sie es beschreiben, aber es ist auch eines dieser notorisch unscheinbaren / zerbrechlichen Dinge (wie Bytearrays oder bloße Zeiger), die Bibliotheken mit ihren verdammtesten Mitteln versuchen, sich zu verstecken.Das ist ein ausgezeichnetes Gespräch von jemandem, der wirklich weiß, wovon er spricht. Ich empfehle den Lesern, sich das Ganze anzuschauen. Es ist nur 36 Minuten lang.
Einer seiner Hauptpunkte ist, dass Einfachheit später Möglichkeiten für Veränderungen eröffnet. Die Auswahl einer Klasse zur Darstellung einer
Person
API bietet den unmittelbaren Vorteil, eine statisch überprüfbare API zu erstellen, wie Sie bereits betont haben. Dies ist jedoch mit den Kosten verbunden, die durch die Begrenzung von Opportunities oder die Erhöhung der Kosten für Änderungen und spätere Wiederverwendung entstehen.Sein Punkt ist, dass die Verwendung der Klasse eine vernünftige Wahl sein könnte, aber es sollte eine bewusste Wahl sein, die sich ihrer Kosten voll bewusst ist, und Programmierer leisten traditionell einen sehr schlechten Job darin, diese Kosten zu bemerken, geschweige denn sie zu berücksichtigen. Diese Wahl sollte neu bewertet werden, wenn Ihre Anforderungen wachsen.
Im Folgenden sind einige Codeänderungen aufgeführt (von denen eine oder zwei im Vortrag erwähnt wurden), die potenziell einfacher sind, wenn eine Liste von Karten verwendet wird, als wenn eine Liste von
Person
Objekten verwendet wird:Map
Primitive in ein übertragbares Format zu setzen, ist in hohem Maße wiederverwendbar und kann sogar in einer Bibliothek bereitgestellt werden. EinPerson
Objekt benötigt wahrscheinlich benutzerdefinierten Code, um denselben Job auszuführen.)Wir lösen diese Probleme ständig und verfügen über Muster und Werkzeuge, denken jedoch nur selten darüber nach, ob die Wahl einer einfacheren und flexibleren Datendarstellung am Anfang unsere Arbeit erleichtert hätte.
quelle
Choosing a class to represent a Person provides the immediate benefit of creating a statically-verifiable API... but that comes with the cost of limiting opportunities or increasing costs for change and reuse later on.
Falsch und unglaublich unaufrichtig. Dies verbessert die Möglichkeit für spätere Änderungen, da der Compiler bei Änderungen automatisch alle Stellen findet und darauf hinweist, die aktualisiert werden müssen, um die gesamte Codebasis auf den neuesten Stand zu bringen. Es ist in dynamischem Code, wo Sie das nicht können, dass Sie wirklich mit früheren Entscheidungen verbunden werden!Verwenden Sie eine Karte, wenn die Daten nur wenig oder gar kein Verhalten aufweisen und sich der flexible Inhalt wahrscheinlich ändert. IMO, ein typischer „javabean“ oder „Data Object“ , das aus einem besteht Anemic Domain Model mit N Feldern, N - Setter und N - Getter ist eine Verschwendung von Zeit. Versuchen Sie nicht, andere mit Ihrer verherrlichten Struktur zu beeindrucken, indem Sie sie in eine schicke Klasse einwickeln. Seien Sie ehrlich, machen Sie Ihre Absichten klar und verwenden Sie eine Karte. (Oder, wenn es für Ihre Domain sinnvoll ist, ein JSON- oder XML-Objekt)
Wenn die Daten ein signifikantes tatsächliches Verhalten aufweisen, auch bekannt als Methoden ( Tell, Don't Ask ), verwenden Sie eine Klasse. Und klopfe dir auf die Schulter, um echte objektorientierte Programmierung zu nutzen :-).
Verwenden Sie eine Klasse, wenn die Daten viele wichtige Validierungsfunktionen und erforderliche Felder aufweisen.
Wenn die Daten ein mäßiges Validierungsverhalten aufweisen, ist dies grenzwertig.
Wenn die Daten Eigenschaftsänderungsereignisse auslösen, ist dies mit einer Karte tatsächlich einfacher und weitaus weniger mühsam. Schreiben Sie einfach eine kleine Unterklasse.
Ein Hauptnachteil der Verwendung einer Map besteht darin, dass der Benutzer die Werte in Strings, ints, Foos usw. umwandeln muss. Wenn dies sehr ärgerlich und fehleranfällig ist, ziehen Sie eine Klasse in Betracht. Oder stellen Sie sich eine Hilfsklasse vor, die die Karte mit den relevanten Gettern umschließt.
quelle
Die API für a
map
hat zwei Ebenen.Die API kann gemäß Konvention in der Map beschrieben werden. Zum Beispiel kann das Paar
:api api-validate
in der Karte platziert werden oder:api-foo validate-foo
könnte die Konvention sein. Die Karte kann sogar gespeichert werdenapi api-documentation-link
.Durch die Verwendung von Konventionen kann der Programmierer eine domänenspezifische Sprache erstellen, die den Zugriff über "Typen" hinweg standardisiert, die als Zuordnungen implementiert sind. Mit
(keys map)
können Eigenschaften zur Laufzeit bestimmt werden.Karten haben nichts Magisches und Objekte nichts Magisches. Es ist alles Versand.
quelle