2009-09-19 13 views
20

Momentan habe ich mich sehr für dieses "Design Pattern" interessiert. Ich bin mir jedoch nicht sicher, ob es bei der Umsetzung dieser strikten globalen Staatsform zu Rückgängen kommt. Also, wann denkst du nicht Singleton in einer Anwendung zu üben?Singleton Design Pattern: Fallstricke

+0

[Hier] (https://www.michaelsafyan.com/tech/design/patterns/singleton) ist eine gute Lesung auf Singleton als ein Anti-Muster. – RBT

Antwort

35

Singleton ist im Allgemeinen eine schlechte Idee, wenn Sie Unit-Tests durchführen, und es ist generell eine schlechte Idee, Unit-Tests (oder BDD oder Acceptance Testing) nicht durchzuführen.

Objekte global zu definieren bedeutet, dass die Unit-Tests, die Sie mit diesen Objekten schreiben, isoliert und voneinander getrennt sind. Stattdessen müssen Sie sich darum kümmern, den Status für jeden Test zurückzusetzen und glauben Sie mir ... das ist nie in 100% der Fälle erledigt. Wenn Sie den globalen Status nicht zurücksetzen, werden Sie sehr seltsam und schwer, Fehler in Ihren Tests zu debuggen, die Zeit verschwenden.

Der globale Status erhöht auch die Kopplung in Ihrem Code und macht die Umgestaltung sehr schwierig.

Die ideale Methode wäre die Verwendung eines IoC/DI-Containers (Spring, Guice usw.), um Objekte anzufordern. Diese Container haben oft Möglichkeiten, Objekte als "Singletons" erscheinen zu lassen, aber sie haben auch Möglichkeiten, dieses Verhalten situationsabhängig zu modifizieren (z. B. Komponententests oder Domänencode).

Das hängt natürlich von der Größe Ihres Problems ab. Wenn Sie einen 4-Klassen-Test-Rig zusammenhacken, um etwas auszuprobieren, dann fahren Sie fort und verwenden Sie einen Singleton. Sobald dieses Projekt jedoch Leben erweckt und größer und komplexer wird, reformieren Sie das Singleton.

+0

Also meinst du, dass Singletons sind * nie * geeignet für die Verwendung in realen Projekten (und die Entdeckung eines Singleton in einem realen Projekt automatisch entspricht Code Geruch unabhängig von der Anwendungsfall)? – Pacerier

+0

Ich rieche einen Troll ... –

+0

Unterlassen Sie es dann, sich selbst zu riechen. Ihre Antwort legt nahe, dass Singletons nur für den Code der "Anfangsphase" verwendet werden und in allen ausgereiften Projekten, die größer werden, ausgeklammert werden sollten. Also meinst du, dass Singletons niemals für die Verwendung in diesen Projekten geeignet sind, oder gibt es gültige Anwendungsfälle? – Pacerier

3

Ich würde ein Singleton sehr selten verwenden. Aufgrund ihrer Beschaffenheit (statische, globale Objekte) sind sie in der Unit-Prüfung Ihres Codes schwierig zu verwenden. Am Ende müssen Sie eine Synchronisierung durchführen oder Mechanismen zur Neuinitialisierung einrichten, damit Sie für jeden Komponententest eine neue Version erhalten. Es gibt Fälle, die einen Sinn ergeben - zum Beispiel eine globale Konfigurationsklasse -, aber sie sind viel weniger, als Menschen, denen Singleton neu ist, zu glauben scheinen. Ich weiß, dass ich eine Phase durchging, in der ich Anwendungen des Singleton-Musters überall sah. Jetzt vermeide ich es, wo immer ich kann, und mache es durch Refactoring in meinem Code rückgängig, wenn ich auf eine unnötige Implementierung stoße.

7

Zusätzlich zu den Test- und Designproblemen, die in anderen Posts erwähnt werden, gibt es Probleme mit Singletons und Classloadern. Singletons sind nicht wirklich "single" pro JVM oder Anwendung - sie erreichen dies durch die statische Eigenschaft, was wirklich bedeutet, dass es einen pro Klasse gibt. Wenn es mehrere Klassenladeprogramme gibt - wie in den meisten Anwendungsservern - erhält jede einzelne Anwendung einen neuen Klassenlader, sogar mehrere Ebenen von Klassenladeprogrammen werden in EJB verwendet. Eine Singleton-Instanz wird pro Klassenlader geladen. Je nachdem, was Sie mit dem Singleton machen, werden die erwarteten Ergebnisse möglicherweise nicht erzielt.

+1

@Nate, das klingt interessant, Könnten Sie mir ein konkretes Beispiel geben? – eric2323223

+0

Gibt es maßgebliche Quellen für Ihren Anspruch? Warum sollten Instanzen von JRE nicht separate Instanzen von Singletons verwenden? – Pacerier

+0

@Pacerier http://www.oracle.com/technetwork/articles/java/singleton-1577166.html Separate JREs mit separaten Singleton-Instanzen ist der erwartete Fall - das Problem ist eine einzelne JRE kann mehrere Klassenlader und damit mehrere Singleton-Instanzen haben . – Nate

18

Google Tech Talks hatte vor einiger Zeit eine gute Präsentation über Global State and Singletons. Das statische Singleton-Muster ist böse, weil es unerwünschte Nebenwirkungen verursacht und den Code nicht testbar macht. Statischer Singleton ist die OO-Version von globalen Variablen.

Die Lösung ist nur eine Instanz des Objekts erstellen und übergeben Sie es durch Dependency-Injektion an seine Benutzer. DI-Frameworks, wie Guice, machen es einfach, die gute Art von Singletons zu definieren (in Guice nur eine Klasse mit @Singleton annotieren). Es gab einen ähnlichen Tech Talk namens Don't Look For Things!, der DI mehr diskutierte.

Verwandte Themen