Ich möchte fragen - ich lerne langsam jQuery.
Was ich sehe, ist ein genaues Beispiel für ein Gott-Objekt-Anti-Muster . Grundsätzlich geht alles auf die $
Funktion, was auch immer es ist.
Habe ich recht und ist jQuery wirklich ein Beispiel für dieses Anti-Pattern?
jquery
anti-patterns
Karel Bílek
quelle
quelle
$
Funktion noch einjQuery
Objekt erfordertAntworten:
Um diese Frage zu beantworten, stelle ich Ihnen eine rhetorische Frage zu einer anderen Struktur, die ähnliche Eigenschaften wie die von jQuery manipulierten DOM-Elemente aufweist, nämlich dem guten alten Iterator. Die Frage ist:
Wie viele weitere Bedienung Sie müssen auf einem einfachen Iterator?
Die Frage kann einfach beantwortet werden, indem Sie sich eine Iterator-API in einer bestimmten Sprache ansehen. Sie benötigen 3 Methoden:
Das ist alles was du brauchst. Wenn Sie diese 3 Operationen ausführen können, können Sie eine beliebige Folge von Elementen durchlaufen.
Aber das ist nicht nur das, was Sie normalerweise mit einer Abfolge von Elementen tun möchten, oder? Sie haben normalerweise ein viel höheres Ziel zu erreichen. Möglicherweise möchten Sie mit jedem Element etwas tun, Sie möchten sie nach bestimmten Bedingungen oder einer von mehreren anderen Methoden filtern. Weitere Beispiele finden Sie in der IEnumerable-Schnittstelle in der LINQ-Bibliothek in .NET.
Sehen Sie, wie viele es gibt? Und das ist nur eine Teilmenge aller Methoden, die sie für die IEnumerable-Schnittstelle hätten verwenden können, da Sie sie normalerweise kombinieren, um noch höhere Ziele zu erreichen.
Aber hier ist die Wendung. Diese Methoden befinden sich nicht in der IEnumerable-Schnittstelle. Dies sind einfache Dienstprogrammmethoden, die einen IEnumerable als Eingabe verwenden und damit etwas anfangen. Während es sich in der C # -Sprache so anfühlt, als gäbe es eine Vielzahl von Methoden für die IEnumerable-Schnittstelle, ist IEnumerable kein Gott-Objekt.
Nun zurück zu jQuery. Stellen wir diese Frage noch einmal, diesmal mit einem DOM-Element.
Wie viele Operationen benötigen Sie für ein DOM-Element?
Auch hier ist die Antwort ziemlich einfach. Alle Methoden, die Sie benötigen, sind Methoden zum Lesen / Ändern der Attribute und der untergeordneten Elemente. Das ist alles. Alles andere ist nur eine Kombination dieser Grundoperationen.
Aber wie viel mehr wollen Sie mit DOM-Elementen anfangen? Nun, genau wie ein Iterator: eine Bajillion verschiedener Dinge. Und hier kommt jQuery ins Spiel. JQuery bietet im Wesentlichen zwei Dinge:
Wenn Sie die gezuckerte Form herausnehmen, erkennen Sie, dass jQuery leicht als eine Reihe von Funktionen geschrieben worden sein könnte, die DOM-Elemente auswählen / ändern. Zum Beispiel:
... hätte geschrieben werden können als:
Semantisch ist es genau dasselbe. Das erste Formular hat jedoch den großen Vorteil, dass die Reihenfolge von links nach rechts der Reihenfolge folgt, in der die Operationen ausgeführt werden. Der zweite Start in der Mitte, der das Lesen von Code erschwert, wenn Sie viele Operationen miteinander kombinieren.
Was bedeutet das alles? Diese jQuery (wie LINQ) ist nicht das Gott-Objekt-Anti-Pattern. Stattdessen handelt es sich um ein sehr angesehenes Muster, das als Dekorateur bezeichnet wird .
Aber was ist mit der Außerkraftsetzung
$
all dieser verschiedenen Dinge? Nun, das ist wirklich nur syntaktischer Zucker. Alle Aufrufe von$
und ihre Ableitungen wie$.getJson()
sind völlig unterschiedliche Dinge, die zufällig ähnliche Namen haben, sodass Sie sofort spüren können, dass sie zu jQuery gehören.$
Führt nur eine Aufgabe aus: Geben Sie einen leicht erkennbaren Ausgangspunkt für die Verwendung von jQuery an. Und all diese Methoden, die Sie für ein jQuery-Objekt aufrufen können, sind kein Symptom für ein God-Objekt. Hierbei handelt es sich einfach um verschiedene Dienstprogrammfunktionen, die jeweils ein und dasselbe für ein als Argument übergebenes DOM-Element ausführen. Die .dot-Notation ist nur hier, weil sie das Schreiben von Code erleichtert.quelle
Nein - die
$
Funktion ist eigentlich nur für drei Aufgaben überladen . Alles andere sind untergeordnete Funktionen, die es nur als Namespace verwenden .quelle
Math
. Da es in JS keinen eingebauten Namespace gibt, wird nur ein Objekt dafür verwendet. Obwohl ich nicht sicher bin, was die Alternative wäre? Alle Funktionen und Eigenschaften in den globalen Namespace stellen?Die jQuery-Hauptfunktion (z. B.
$("div a")
) ist im Wesentlichen eine Factory-Methode, die eine Instanz des jQuery-Typs zurückgibt , die eine Auflistung von DOM-Elementen darstellt.Diese Instanzen des Typs jQuery verfügen über eine große Anzahl von DOM-Manipulationsmethoden, die auf die von der Instanz dargestellten DOM-Elemente angewendet werden. Während dies möglicherweise als eine Klasse angesehen werden könnte, die zu groß geworden ist, passt es nicht wirklich zum Gott-Objekt-Muster.
Schließlich gibt es, wie Michael Borgwardt erwähnt, auch eine große Anzahl von Dienstprogrammfunktionen, die $ als Namespace verwenden und sich nur tangential auf die jQuery-Objekte der DOM-Sammlung beziehen.
quelle
$
ist kein Objekt, es ist ein Namespace.Würden Sie java.lang wegen der vielen Klassen, die es enthält, als Gottobjekt bezeichnen? Das Aufrufen
java.lang.String.format(...)
ist eine absolut gültige Syntax, die in der Form dem Aufrufen von Elementen in jQuery sehr ähnlich ist.Ein Objekt, um ein Gott-Objekt zu sein, muss in erster Linie ein geeignetes Objekt sein - das sowohl Daten als auch die Intelligenz enthält, um auf die Daten einzuwirken. jQuery enthält nur die Methoden.
Eine andere Sichtweise: Ein gutes Maß dafür, wie viel von einem Gottobjekt ein Objekt ist, ist der Zusammenhalt - ein geringerer Zusammenhalt bedeutet mehr von einem Gottobjekt. Kohäsion besagt, wie viele der Daten von wie vielen Methoden verwendet werden. Da in jQuery keine Daten vorhanden sind, berechnen Sie die Daten - alle Methoden verwenden alle Daten, sodass jQuery einen hohen Zusammenhalt aufweist und somit kein Gott-Objekt ist.
quelle
Benjamin hat mich gebeten, meine Position zu klären, also habe ich meinen vorherigen Beitrag bearbeitet und weitere Gedanken hinzugefügt.
Bob Martin ist der Autor eines großartigen Buches mit dem Titel Clean Code. In diesem Buch gibt es ein Kapitel (Kapitel 6) mit dem Titel Objekte und Datenstrukturen, in dem er die wichtigsten Unterschiede zwischen Objekten und Datenstrukturen und die Behauptungen, dass wir zwischen ihnen wählen müssen, beschreibt, da das Mischen von Objekten eine sehr schlechte Idee ist.
Ich denke, DOM ist ein Beispiel für diese Objekt- und Datenstruktur-Hybride. Zum Beispiel schreiben wir mit DOM Codes wie diesen:
DOM sollte eindeutig eine Datenstruktur anstelle eines Hybrids sein.
Das jQuery-Framework besteht aus einer Reihe von Prozeduren, mit denen Sie eine Sammlung von DOM-Knoten auswählen und ändern und viele andere Aufgaben ausführen können. Wie Laurent in seinem Beitrag betonte, ist jQuery so etwas unter der Haube:
Die Entwickler von jQuery haben alle diese Prozeduren in einer einzigen Klasse zusammengefasst, die für alle oben aufgeführten Funktionen verantwortlich ist. Es verstößt also eindeutig gegen das Prinzip der Einzelverantwortung und ist somit ein göttlicher Gegenstand. Das einzige, weil es nichts kaputt macht, weil es eine einzelne Standalone-Klasse ist, die mit einer einzelnen Datenstruktur (der Auflistung von DOM-Knoten) arbeitet. Wenn wir jQuery-Unterklassen oder eine andere Datenstruktur hinzufügen würden, würde das Projekt sehr schnell zusammenbrechen. Ich glaube also nicht, dass wir mit jQuery über oo sprechen können, es ist eher prozedural als oo, obwohl es eine Klasse definiert.
Was Laurent behauptet, ist ein völliger Unsinn:
Beim Decorator-Muster geht es darum, neue Funktionen hinzuzufügen, indem die Benutzeroberfläche beibehalten und vorhandene Klassen nicht geändert werden. Zum Beispiel:
Sie können 2 Klassen definieren, die die gleiche Schnittstelle implementieren, jedoch mit einer völlig anderen Implementierung:
Wenn Sie über Methoden verfügen, die nur die gemeinsame Schnittstelle verwenden, können Sie einen oder mehrere Decoratoren definieren, anstatt denselben Code zwischen A und B einzufügen. Sie können diese Decoratoren auch in einer verschachtelten Struktur verwenden.
Sie können also die ursprünglichen Instanzen durch die Decorator-Instanzen in Code höherer Abstraktionsebene ersetzen.
Die Schlussfolgerung, dass jQuery kein Decorator von irgendetwas ist, weil es nicht die gleiche Schnittstelle wie Array, NodeList oder ein anderes DOM-Objekt implementiert. Es implementiert eine eigene Schnittstelle. Die Module werden auch nicht als Dekorateure verwendet, sondern überschreiben einfach den ursprünglichen Prototyp. Das Decorator-Muster wird also nicht in der gesamten jQuery-Bibliothek verwendet. Die jQuery-Klasse ist einfach ein riesiger Adapter, mit dem wir dieselbe API von vielen verschiedenen Browsern verwenden können. Aus oo Perspektive ist es ein komplettes Durcheinander, aber das ist nicht wirklich wichtig, es funktioniert gut und wir benutzen es.
quelle