Nennen Sie die Entwurfsüberlegungen bei der Entscheidung zwischen der Verwendung eines Singletons und einer statischen Klasse. Auf diese Weise sind Sie gezwungen, die beiden zu kontrastieren. Welche Kontraste Sie auch finden können, ist auch nützlich, um Ihren Denkprozess zu zeigen! Außerdem sieht jeder Interviewer gerne anschauliche Beispiele. :) :)
design-patterns
cdleary
quelle
quelle
Antworten:
quelle
Wie wäre es mit "beides vermeiden"? Singletons und statische Klassen:
Schauen Sie sich stattdessen Dependency Injection und Inversion von Control Container- Bibliotheken an. Mehrere der IoC-Bibliotheken übernehmen die Lebensdauerverwaltung für Sie.
(Wie immer gibt es Ausnahmen wie statische Mathematikklassen und C # -Erweiterungsmethoden.)
quelle
Hide Dependencies
kleine Seiteninfo zu diesem Punkt: Sie können das Inversion of Control-Muster beispielsweise mithilfe von Ninject implementieren . Auf diese Weise können Sie nur eine Instanz eines Typs verwenden, indem Sie ihn an a binden. DiesSingletonScope
bedeutet, dass immer dieselbe Instanz injiziert wird, die Klasse jedoch kein Singleton ist.Ich würde behaupten, der einzige Unterschied ist die Syntax: MySingleton.Current.Whatever () vs MySingleton.Whatever (). Der Staat ist, wie David erwähnte, in beiden Fällen letztendlich "statisch".
EDIT: Die Beerdigungsbrigade kam von Digg ... jedenfalls dachte ich an einen Fall, der einen Singleton erfordern würde. Statische Klassen können weder von einer Basisklasse erben noch eine Schnittstelle implementieren (zumindest in .NET können sie dies nicht). Wenn Sie diese Funktionalität benötigen, müssen Sie einen Singleton verwenden.
quelle
Eine meiner Lieblingsdiskussionen zu diesem Thema ist hier (ursprüngliche Website nicht verfügbar, jetzt mit Internet Archive Wayback Machine verknüpft ).
Um die Flexibilitätsvorteile eines Singleton zusammenzufassen:
quelle
Eine statische Klasse mit einer Menge statischer Variablen ist ein Hack.
Ein Singleton mit einer tatsächlichen Instanz ist besser.
Der Status befindet sich NUR in der Instanz.
So kann der Singleton später geändert werden, um Pooling, threadlokale Instanzen usw. durchzuführen. Und keiner der bereits geschriebenen Codes muss geändert werden, um den Vorteil zu erzielen.
Es ist möglich, mit einer statischen Klasse etwas Ähnliches zu tun, aber der indirekte Versand verursacht einen Overhead pro Anruf.
Sie können die Instanz abrufen und als Argument an eine Funktion übergeben. Dadurch kann der Code an den "richtigen" Singleton gerichtet werden. Wir wissen, dass Sie nur eines davon brauchen ... bis Sie es nicht tun.
Der große Vorteil besteht darin, dass zustandsbehaftete Singletons threadsicher gemacht werden können, während eine statische Klasse dies nicht kann, es sei denn, Sie ändern sie als geheimen Singleton.
quelle
Stellen Sie sich einen Singleton wie einen Dienst vor. Es ist ein Objekt, das eine bestimmte Reihe von Funktionen bietet. Z.B
Die Objektfactory ist ein Objekt, das einen bestimmten Dienst ausführt.
Im Gegensatz dazu ist eine Klasse voller statischer Methoden eine Sammlung von Aktionen, die Sie möglicherweise ausführen möchten, organisiert in einer verwandten Gruppe (Die Klasse). Z.B
Das StringUtils-Beispiel hier ist eine Sammlung von Funktionen, die überall angewendet werden können. Das Singleton-Factory-Objekt ist ein bestimmter Objekttyp mit einer eindeutigen Verantwortung, der bei Bedarf erstellt und weitergegeben werden kann.
quelle
Statische Klassen werden zur Laufzeit instanziiert. Dies kann zeitaufwändig sein. Singletons können nur bei Bedarf instanziiert werden.
quelle
Singletons sollten nicht wie statische Klassen verwendet werden. Im Wesentlichen
ist im Wesentlichen das gleiche wie
Was Sie eigentlich tun sollten, ist , den Singleton als ein weiteres Objekt zu behandeln . Wenn für einen Dienst eine Instanz vom Typ Singleton erforderlich ist, übergeben Sie diese Instanz im Konstruktor:
Der Dienst sollte nicht wissen, dass das Objekt ein Singleton ist, und das Objekt nur als Objekt behandeln.
Das Objekt kann sicherlich als Implementierungsdetail und als Aspekt der Gesamtkonfiguration als Singleton implementiert werden, wenn dies die Dinge einfacher macht. Die Dinge, die das Objekt verwenden, sollten jedoch nicht wissen müssen, ob das Objekt ein Singleton ist oder nicht.
quelle
Wenn mit "statische Klasse" eine Klasse gemeint ist, die nur statische Variablen enthält, können sie tatsächlich den Status beibehalten. Mein Verständnis ist, dass der einzige Unterschied darin besteht, wie Sie auf dieses Ding zugreifen. Beispielsweise:
gegen
Die Interna von MySingleton unterscheiden sich offensichtlich zwischen ihnen, aber abgesehen von Thread-Sicherheitsproblemen werden beide hinsichtlich des Client-Codes die gleiche Leistung erbringen.
quelle
Das Singleton-Muster wird im Allgemeinen verwendet, um instanzunabhängige oder statische Daten zu bedienen, bei denen mehrere Threads gleichzeitig auf Daten zugreifen können. Ein Beispiel können Statuscodes sein.
quelle
Singletons sollten niemals verwendet werden (es sei denn, Sie betrachten eine Klasse ohne veränderlichen Status als Singleton). "statische Klassen" sollten keinen veränderlichen Zustand haben, außer vielleicht threadsicheren Caches und dergleichen.
So ziemlich jedes Beispiel eines Singletons zeigt, wie man es nicht macht.
quelle
Wenn Sie über einen Singleton verfügen können, um ihn zu bereinigen, können Sie ihn in Betracht ziehen, wenn es sich um eine begrenzte Ressource handelt (dh nur eine davon), die Sie nicht ständig benötigen und über eine Art Speicher verfügen oder Ressourcenkosten, wenn es zugewiesen wird.
Der Bereinigungscode sieht natürlicher aus, wenn Sie einen Singleton haben, als eine statische Klasse, die statische Statusfelder enthält.
Der Code sieht jedoch in beiden Fällen ähnlich aus. Wenn Sie also spezifischere Gründe für die Frage haben, sollten Sie dies vielleicht näher erläutern.
quelle
Die beiden können sehr ähnlich sein, aber denken Sie daran, dass der wahre Singleton selbst instanziiert (einmal gewährt) und dann bedient werden muss. Eine PHP-Datenbankklasse, die eine Instanz von zurückgibt,
mysqli
ist nicht wirklich ein Singleton (wie manche Leute es nennen), da sie eine Instanz einer anderen Klasse zurückgibt , keine Instanz der Klasse, die die Instanz als statisches Mitglied hat.Wenn Sie also eine neue Klasse schreiben, von der Sie nur eine Instanz in Ihrem Code zulassen möchten, können Sie sie auch als Singleton schreiben. Stellen Sie sich vor, Sie schreiben eine einfache Jane-Klasse und fügen sie hinzu, um die Anforderung der Einzelinstanziierung zu vereinfachen. Wenn Sie eine andere Klasse verwenden, die Sie nicht ändern können (wie
mysqli
), sollten Sie eine statische Klasse verwenden (auch wenn Sie der Definition nicht das Schlüsselwort voranstellen).quelle
Singletons sind flexibler, was in Fällen nützlich sein kann, in denen die Instanzmethode je nach Kontext verschiedene konkrete Unterklassen des Singleton-Typs zurückgeben soll.
quelle
Statische Klassen können nicht als Argumente weitergegeben werden. Instanzen eines Singleton können sein. Achten Sie, wie in anderen Antworten erwähnt, auf Threading-Probleme mit statischen Klassen.
rp
quelle
Ein Singleton kann einen Konstruktor und einen Destruktor haben. Abhängig von Ihrer Sprache wird der Konstruktor möglicherweise automatisch aufgerufen, wenn Ihr Singleton zum ersten Mal verwendet wird, oder niemals, wenn Ihr Singleton überhaupt nicht verwendet wird. Eine statische Klasse hätte keine solche automatische Initialisierung.
Sobald ein Verweis auf ein Singleton-Objekt erhalten wurde, kann es wie jedes andere Objekt verwendet werden. Der Client-Code muss möglicherweise nicht einmal wissen, dass er einen Singleton verwendet, wenn ein Verweis auf den Singleton früher gespeichert wurde:
Dies erleichtert natürlich die Arbeit, wenn Sie das Singleton-Muster zugunsten eines echten Musters wie IoC ablegen.
quelle
Verwenden Sie das Singleton-Muster, wenn Sie zur Laufzeit etwas berechnen müssen, das Sie zur Kompilierungszeit berechnen würden, wenn Sie könnten, z. B. Nachschlagetabellen.
quelle
Ich denke, ein Ort, an dem Singleton sinnvoller ist als die statische Klasse, ist, wenn Sie einen Pool kostspieliger Ressourcen (wie Datenbankverbindungen) erstellen müssen. Sie wären nicht daran interessiert, den Pool zu erstellen, wenn niemand sie jemals verwendet (statische Klasse bedeutet, dass Sie die kostspielige Arbeit erledigen, wenn die Klasse geladen wird).
quelle
Ein Singleton ist auch eine gute Idee, wenn Sie ein effizientes Zwischenspeichern von Daten erzwingen möchten. Zum Beispiel habe ich eine Klasse, die Definitionen in einem XML-Dokument nachschlägt. Da das Parsen des Dokuments eine Weile dauern kann, habe ich einen Cache mit Definitionen eingerichtet (ich verwende SoftReferences, um outOfmemeoryErrors zu vermeiden). Wenn sich die gewünschte Definition nicht im Cache befindet, mache ich das teure XML-Parsing. Ansonsten gebe ich eine Kopie aus dem Cache zurück. Da mehrere Caches bedeuten würden, dass ich dieselbe Definition möglicherweise noch mehrmals laden muss, muss ich einen statischen Cache haben. Ich habe mich entschieden, diese Klasse als Singleton zu implementieren, damit ich die Klasse nur mit normalen (nicht statischen) Datenelementen schreiben kann. Auf diese Weise kann ich immer noch eine Istantiation der Klasse erstellen, falls ich sie aus irgendeinem Grund benötige (Serialisierung, Komponententests usw.).
quelle
Singleton ist wie ein Dienst, wie bereits erwähnt. Pro ist seine Flexibilität. Statisch, nun, Sie benötigen einige statische Teile, um Singleton zu implementieren.
Singleton verfügt über Code, der sich um die Instanziierung des eigentlichen Objekts kümmert. Dies kann eine große Hilfe sein, wenn Sie auf Rennprobleme stoßen. In einer statischen Lösung müssen Sie möglicherweise Rennprobleme an mehreren Codestandorten lösen.
So wie Singleton mit einigen statischen Variablen erstellt werden kann, können Sie es möglicherweise mit 'goto' vergleichen. Es kann sehr nützlich sein, um andere Strukturen zu bauen, aber Sie müssen wirklich wissen, wie man es benutzt und sollten es nicht "überbeanspruchen". Daher wird allgemein empfohlen, sich an Singleton zu halten und bei Bedarf statisch zu verwenden.
Überprüfen Sie auch den anderen Beitrag: Warum sollten Sie eine statische Klasse einer Singleton-Implementierung vorziehen?
quelle
verweisen Sie dies
Zusammenfassung:
ein. Eine einfache Faustregel, der Sie folgen können, lautet: Wenn der Status nicht beibehalten werden muss, können Sie eine statische Klasse verwenden. Andernfalls sollten Sie einen Singleton verwenden.
b. Verwenden Sie einen Singleton, wenn es sich um ein besonders „schweres“ Objekt handelt. Wenn Ihr Objekt groß ist und eine angemessene Menge an Speicherplatz beansprucht, werden viele n / w-Aufrufe (Verbindungspool) usw. durchgeführt. Um sicherzustellen, dass es nicht mehrmals instanziiert wird. Eine Singleton-Klasse hilft dabei, zu verhindern, dass ein solcher Fall jemals auftritt
quelle
Wenn die einzelne Klasse den Status benötigt. Singletons behalten einen globalen Status bei, statische Klassen nicht.
Erstellen eines Hilfsprogramms für eine Registrierungsklasse: Wenn Sie eine veränderbare Struktur haben (HKey Current User vs. HKEY Local Machine), können Sie Folgendes tun:
Jetzt werden alle weiteren Aufrufe dieses Singletons auf dem Local Machine Hive ausgeführt. Andernfalls müssten Sie bei Verwendung einer statischen Klasse angeben, dass die lokale Maschine jeden Tag enthält, oder eine Methode wie diese verwenden
ReadSubkeyFromLocalMachine
.quelle