it-swarm.com.de

Wann ein Singleton und wann eine statische Klasse verwendet werden soll

Ich habe hier und auf StackOverflow danach gesucht und einige Unterschiede zwischen den beiden gefunden.

Aber ich bin mir immer noch nicht sicher in welchen Fällen würde man einen Singleton bevorzugen und in welchen Fällen würde man eine statische Klasse verwenden.

(In Sprachen, die keine 'statischen Klassen' unterstützen, wie Java, beziehe ich mich offensichtlich auf Klassen, die nur statische Methoden und Felder enthalten).

Bitte geben Sie mir konkrete Beispiele für Fälle, in denen Sie jeden einzelnen auswählen würden, und erklären Sie, warum.

34
Aviv Cohn

Ein Fall, in dem eine statische Klasse eine gute Idee sein könnte, ist, wenn Sie verwandte Funktionen sammeln möchten, aber in keinem Objekt einen internen Status haben müssen. Ein Beispiel könnte die Math-Klasse in Java sein. Es enthält eine ganze Reihe verwandter Funktionen, auf die außerhalb des Kontexts einer bestimmten Objektinstanz zugegriffen wird. Ich habe ähnliche Dinge getan, bei denen eine Reihe allgemeiner Dienstprogrammfunktionen, die an mehreren Stellen in einer Anwendung verwendet werden, zu einer einzigen Dienstprogrammklasse zusammengefasst sind.

Ein Singleton wird verwendet, wenn Sie do ein tatsächliches Objekt (mit seinem eigenen internen Status und allem) möchten und Ihr System auf genau eine Instanz dieses Objekts beschränken möchten. Dies kann nützlich sein, wenn Sie über eine gemeinsam genutzte Ressource verfügen, z. B. eine Datenbank, einen In-Memory-Cache oder eine spezielle Hardware wie einen Roboterarm. Viele Teile Ihres Programms möchten diese Ressource möglicherweise verwenden, und Sie möchten möglicherweise, dass der gesamte Zugriff auf die Ressource über einen einzigen Punkt erfolgt. Ein Singleton ist nicht immer die nur Methode, um mit diesen Situationen umzugehen, aber es ist einer der wenigen Orte, an denen ich denke, dass ein Singleton könnte eine gute Wahl ist.

  • Vermeiden Sie das Singleton-Muster der Viererbande aus den in den anderen Antworten genannten Gründen. Hauptsächlich handelt es sich um ein Anti-Muster, das auf Schwierigkeiten beim Testen beruht.

  • Factory- und Abhängigkeitsinjektion machten Singleton überflüssig. Die beste Antwort ist die Verwendung einer Factory, die entscheidet, ob eine oder mehrere Instanzen einer bestimmten Klasse instanziiert werden sollen. Auf diese Weise sind die Klasse und ihre Clients nicht für ihren Singleton-Status verantwortlich - dies wird zu einem transparenten Problem, das von der Factory verwaltet wird.

  • Abhängigkeitsinjektions-Frameworks wie Spring erledigen dies sofort für Sie (z. B. Spring Beans sind Singletons, sofern Sie nichts anderes angeben).

  • Rein statische Klassen sind sowohl für das Testen als auch für die Verwendung von OO Konzepten) problematisch. Ich habe Teams mit einem unwiderstehlichen Drang gesehen, alles statisch und endgültig zu machen, und die Frage wird: Warum schreiben sie nicht einfach C-Code?

  • Wenn Ihre statische Klasse Nebenwirkungen hat, sollte sie nicht statisch sein. Das heißt, wenn der gemeinsam genutzte Status verwaltet oder der Status von Parametern geändert wird, sollte es sich um eine reguläre Klasse handeln, in der die Factory eine einzelne gemeinsam genutzte Instanz verteilt. Eine rein statische Klasse, die den gemeinsam genutzten Status verwaltet, wird zu einem wirklich schwierigen Testproblem.

  • Eine rein statische Klasse erzeugt auch harte Abhängigkeiten zur Kompilierungszeit von dieser bestimmten Klasse, was die Erweiterungs- und Testfähigkeit Ihres Codes wirklich beeinträchtigt. Scheint, als würden Sie das für etwas Ewiges und Unveränderliches reservieren wollen, ohne Nebenwirkungen, wie mathematische Formeln.

Die Antwort lautet also: Schreiben Sie keine Klassen als Singletons, sondern verschieben Sie diese Entscheidung in Ihre Fabrik. Und in einer OO Sprache) übersehen statische Klassen einige der wichtigsten Entwurfsaspekte der Sprache und erschweren das Testen. Auch hier können Sie Worker-Klassen mit spezifischer Semantik verwenden, um diese zu bündeln und generieren zu lassen von Ihrer Fabrik.

12
Rob

Singletons-Objekte, die so erstellt wurden, dass jeweils nur eine Instanz vorhanden sein kann, können anwendungsweit verwendet werden.

Objekte, die mit Dingen wie Verbindungspools umgehen, sind ein guter Kandidat für Singletons.

  • Sie möchten nur 1 Instanz in der gesamten Anwendung
  • sie müssen von verschiedenen Teilen der Anwendung aus darauf zugreifen können
  • die darin enthaltenen Daten müssen beibehalten werden, auch wenn derzeit keine anderen Objekte darauf verweisen (praktisch, wenn Sie Objekte wiederverwenden möchten, deren Initialisierung teuer ist).

Eine Klasse, die nur mit statischen Methoden gefüllt ist, ist normalerweise nicht dazu gedacht, wie ein Objekt initialisiert zu werden. Es ist eher ein Wrapper für die darin enthaltenen statischen Methoden.

Ein Beispiel dafür, das ich häufig verwende, ist eine Utility-Klasse mit Methoden, die sich wiederholende Aufgaben ausführen, die Parameter annehmen, eine Berechnung mit ihnen durchführen/sie formatieren/etc. und gibt dann das Ergebnis zurück, ohne externe (oder zumindest keine nicht statischen) Felder oder Methoden zu verwenden. Ich initialisiere niemals eine Utility-Klasse, sondern verwende nur die darin enthaltenen statischen Methoden für alle sich wiederholenden Methoden.

Dies ist nur, wie ich dazu neige, Singletons und statische (mit Methoden gefüllte) Klassen zu verwenden, nicht sicher, ob dies "offiziellen" Standards entspricht ...

0
Rob