2009-09-19 3 views
20

Attualmente sono stato molto interessato a questo "modello di progettazione". Non sono sicuro, tuttavia, se ci siano dei problemi con questa implementazione rigorosa dello stato globale. Quindi, quando pensi di non praticare singleton in un'applicazione?Singleton Design Pattern: Pitfalls

+0

[qui] (https://www.michaelsafyan.com/tech/design/patterns/singleton) è una buona lettura su Singleton essere un anti-modello. – RBT

risposta

35

Singleton è in genere una cattiva idea se si eseguono test di unità e generalmente è una cattiva idea non eseguire il test dell'unità (o BDD o Acceptance Testing).

La creazione di oggetti con stato globale indica che l'unità verifica che la scrittura implicante questi oggetti sia isolata e disgiunta l'una dall'altra. Invece, dovrai preoccuparti di reimpostare lo stato per ogni test e credimi ... non è mai stato fatto al 100% del tempo. Se non si ripristina lo stato globale, si inizia a ottenere errori molto bizzarri e difficili da debug nei test che perdono tempo.

Lo stato globale aumenta anche l'accoppiamento nel codice e rende molto difficile il refactoring.

Il metodo ideale sarebbe utilizzare un contenitore IoC/DI (Spring, Guice, ecc.) Per richiedere oggetti. Questi contenitori hanno spesso il modo di far apparire gli oggetti come "Singletons" ma hanno anche dei modi per modificare quel comportamento a seconda della situazione (cioè test delle unità rispetto al codice del dominio).

Questo dipende ovviamente dalla dimensione del problema. Se stai creando un banco di prova di 4 classi per provare qualcosa, vai avanti e usa Singleton. Tuttavia, non appena quel progetto prende vita e diventa più grande e più complesso, rifatta il Singleton.

+0

Quindi vuoi dire che sono single * mai * idoneo per l'utilizzo in progetti reali (e spotting un Singleton in un vero e proprio progetto automaticamente equivale a odore di codice a prescindere dal caso d'uso)? – Pacerier

+0

Sento odore di troll ... –

+0

Non astenersi dall'odorare te stesso allora. La tua risposta suggerisce che i singleton sono usati solo per il codice della "fase iniziale" e dovrebbero essere presi in considerazione in tutti i progetti maturi che diventano più grandi. Quindi intendi che i singleton non sono mai idonei per l'uso in questi progetti, o ci sono casi d'uso validi? – Pacerier

3

Vorrei usare un Singleton molto raramente. A causa della loro natura (oggetti statici, globali) sono difficili da usare nelle unit test del codice. Finisci per aver bisogno di fare un po 'di sincronizzazione o di costruire in alcuni meccanismi di re-inizializzazione in modo da poter ottenere una nuova versione per ogni unità di test. Ci sono casi che hanno senso - ad esempio, una classe di configurazione globale - ma sono molto meno di quelli che le persone nuove a Singleton sembrano credere. So di aver attraversato una fase in cui ho visto applicazioni del modello singleton ovunque. Ora lo evito dovunque posso e lo annullo tramite il refactoring nel mio codice quando mi imbatto in un'implementazione non necessaria.

7

Oltre ai problemi di test e progettazione menzionati in altri post, ci sono problemi con Singletons e classloaders. I single non sono realmente "single" per JVM o applicazione - lo fanno attraverso la proprietà statica, il che significa che ce n'è uno per classe. Se ci sono più caricatori di classi, come nella maggior parte dei server di app, ciascuna applicazione separata ottiene un nuovo classloader, anche in EJB vengono utilizzati più livelli di classloader. Un'istanza singleton viene caricata per classloader, che a seconda di cosa stai facendo con il singleton, potrebbe non produrre i risultati che ti aspetti.

+1

@Nate, sembra interessante, potresti darmi un esempio concreto? – eric2323223

+0

Esistono fonti autorevoli per il reclamo? Perché non separare le istanze di JRE utilizzare istanze separate di singleton? – Pacerier

+0

@Pacerier http://www.oracle.com/technetwork/articles/java/singleton-1577166.html Separare i JRE utilizzando istanze singleton separate è il caso previsto - il problema è che un singolo JRE può avere più classloader e quindi più istanze singleton . – Nate

18

Google Tech Talks ha avuto qualche tempo fa una buona presentazione su Global State and Singletons. Il modello statico di singleton è malvagio, perché causa effetti collaterali indesiderati e rende il codice non verificabile. Static singleton è la versione OO delle variabili globali.

La soluzione è è sufficiente creare un'istanza dell'oggetto e passarlo ai propri utenti tramite l'integrazione delle dipendenze. I framework DI, come Guice, rendono semplice la definizione del buon tipo di singletons (in Guice basta annotare una classe con @Singleton). C'era un simile Tech Talk chiamato Don't Look For Things! che discuteva di DI altro.