Ich bin oft mit Helfer- oder Util-Klassen in Java oder einer anderen Sprache konfrontiert. Also habe ich mich gefragt, ob dies eine Art Anti-Pattern ist und ob die Existenz solcher Klassen nur ein Mangel an Fehlern im Design und in der Architektur einer Software ist.
Oft werden diese Klassen nur mit statischen Methoden begrenzt, die eine Menge Dinge tun. Aber meistens ist es in der Tat kontextabhängig und staatlich.
Meine Frage ist, was ist Ihre Meinung zu solchen statischen Helfer- / Util-Klassen, da der Vorteil natürlich der schnelle Aufruf ist, der nur den Klassennamen verwendet.
Und auf welcher Abstraktionsebene würden Sie solche Klassen vermeiden?
Meiner Meinung nach sollte das Schlüsselwort "static" nur innerhalb der Deklaration einer Klasse (Java) und nicht für Methoden zulässig sein. Meiner Meinung nach könnte es eine gute Alternative sein, Procuedural- und OO-Paradigmen in Java zu kombinieren und einen Missbrauch des Schlüsselworts zu vermeiden.
Ergänzungen aufgrund der Antworten:
Zunächst denke ich, dass es völlig legal ist, verschiedene Paradigmen zu kombinieren und sogar Laufzeit-interpretierte Skriptsprachen in maschinen- oder vm-kompiliertem Code zu verwenden.
Ich habe die Erfahrung gemacht, dass während des Entwicklungsprozesses eines Projekts solche Helfer und Hilfsmittel oder wie auch immer der Name lautet, immer weiter wachsen und in jeder vergessenen Ecke der Codebasis verwendet werden, die ursprünglich modular und flexibel gestaltet war. Und aufgrund von Zeitmangel, um Überarbeitungen vorzunehmen oder das Design erneut zu überdenken, wird es im Laufe der Zeit nur noch viel schlimmer.
Ich denke, static
sollte aus Java entfernt werden. Besonders jetzt, wo es möglich ist, noch ausgefeiltere funktionale Sprachelemente zu verwenden.
quelle
Antworten:
Nun, Java hat keine freien Funktionen, so dass Sie gezwungen sind, diese als statische Funktionen in eine Pro-Forma-Klasse zu schreiben. Ein notwendiger Workaround ist niemals ein Anti-Pattern, obwohl ihm möglicherweise die Eleganz fehlt.
Als nächstes ist nichts falsch an freien Funktionen. Tatsächlich reduziert die Verwendung freier Funktionen die Kopplung, da sie statt aller wichtigen Details nur Zugriff auf die öffentliche Schnittstelle haben.
Natürlich mindert die Verwendung von freien / statischen Funktionen in keiner Weise die Gefahren eines veränderlichen, gemeinsam genutzten, insbesondere globalen Zustands.
quelle
this
und erfordern, dass etwas entsprechend instanziiert wirdStatische Hilfsprogramm- oder Hilfsfunktionen sind kein Antimuster, wenn sie bestimmten Richtlinien entsprechen:
Sie sollten frei von Nebenwirkungen sein
Sie werden für anwendungsspezifisches Verhalten verwendet, das nicht zu der Klasse oder den Klassen gehört, für die diese Funktionen ausgeführt werden
Sie benötigen keinen gemeinsamen Status
Häufige Anwendungsfälle:
Zum Beispiel habe ich in einer Anwendung an Benutzern gearbeitet, die Journaleinträge für ihre Aktivitäten führen. Sie können ein Follow-up-Datum festlegen und eine Ereigniserinnerung herunterladen. Wir haben eine statische Utility-Klasse erstellt, um einen Journaleintrag aufzunehmen und den Rohtext für eine .ics-Datei zurückzugeben.
Es war kein gemeinsamer Staat erforderlich. Es hat keinen Zustand verändert, und das Erstellen eines iCal-Ereignisses war sicherlich anwendungsspezifisch und gehörte nicht zur Journaleintragsklasse.
Wenn die statischen Funktionen oder Dienstprogrammklassen Nebenwirkungen haben oder den gemeinsamen Status erfordern, würde ich empfehlen, diesen Code neu zu bewerten, da hierdurch eine Kopplung eingeführt wird, die für Komponententests möglicherweise schwierig zu verspotten ist.
quelle
Es wird von Ihrer Herangehensweise abhängen. Viele Anwendungen sind funktionaler als die klassische Denkweise (einschließlich eines Großteils der Websites, auf denen Sie sich befinden).
Mit dieser Einstellung gibt es viele Dienstprogrammmethoden für Worker-Klassen, die als statische Methoden aneinandergereiht werden können. Sie werden näher an einfache Objekte gefüttert / verwendet, die nur Daten enthalten und weitergegeben werden.
Es ist ein gültiger Ansatz und kann sehr gut funktionieren, insbesondere im Maßstab.
quelle
Agent.Save(obj)
vs.agentInstance.Save(obj)
. Mit letzterem haben Sie die Möglichkeit ,agentInstance
in den Verwendungscode einzufügen. Infolgedessen können Sie jede untergeordnete Klasse vonAgent
auch injizieren, was die Wiederverwendung des Verwendungscodes mit verschiedenen "Typen" vonAgent
ohne Neukompilierung ermöglicht. Dies ist eine niedrige Kopplung .Ich persönlich denke, das einzig Wichtige an solchen Helferklassen ist, dass sie privat gemacht werden. Ansonsten sind sie eine gute Idee (sparsam angewendet).
Die Art und Weise, wie ich das sehe, ist, wenn bei der Implementierung einer Klasse (oder Funktion) so etwas hilfreich ist und die Implementierung klarer macht, wie könnte das schlecht sein? Und OFTEN ist es wichtig, solche privaten Helferklassen zu definieren, um die Integration und Verwendung anderer Algorithmen zu ermöglichen, die davon abhängen, dass Daten in einer bestimmten Form vorliegen.
Ob es als "Helfer" bezeichnet wird, ist eine kleine Sache des persönlichen Geschmacks, aber es bedeutet, dass es bei der Implementierung hilft und für ein breiteres Publikum nicht von Interesse / Nutzen ist. Wenn das Sinn macht - machen Sie es!
quelle
java.lang.Math
.Die Verbreitung von
static
Helferklassen beruht auf einem Missverständnis. Nur weil wir Klassen nur mitstatic
Methoden "Dienstprogrammklassen" aufrufen, heißt das nicht, dass es nicht erlaubt ist, allgemeines Verhalten in POJOs zu schreiben.static
Hilfsklassen sind aus drei Gründen Anti-Pattern:Durch den statischen Zugriff auf diese Hilfsmethode werden Abhängigkeiten ausgeblendet . Wenn diese "Dienstprogrammklassen" POJOs wären, könnten Sie sie als Konstruktorparameter in eine abhängige Klasse einfügen, wodurch die Abhängigkeit für jeden Benutzer einer abhängigen Klasse offensichtlich wird.
Der statische Zugriff auf diese Hilfsmethoden führt zu einer dichten Kopplung . Dies bedeutet, dass der Code mit den Hilfsmethoden nur schwer wiederverwendbar und (als Nebeneffekt) schwer zu testen ist.
Insbesondere wenn sie den Status beibehalten, handelt es sich lediglich um globale Variablen . Und hoffentlich argumentiert niemand, dass globale Variablen gut sind ...
Statische Hilfsklassen sind Teil des STUPID-Code- Anti-Patterns.
Das OP schrieb:
Statische Statefull-Konstrukte sind globale Zustände.
Ja, natürlich. Und fast alle Anwendungen benötigen einen globalen Status .
Aber globaler Zustand ! = Globale Variable .
Sie können einen globalen Status mit OO-Techniken über die Abhängigkeitsinjektion erstellen. Sie können jedoch einen globalen Status nicht mit statischen Statusstrukturen vermeiden, bei denen es sich im unteren Bereich um globale Variablen handelt .
quelle
Func<Result, Args>
Objekte, die an anderer Stelle instanziiert werden.