Ho visto alcune persone in SO che commentano che Singleton Pattern è un anti-pattern. Voglio sapere perché?Perché l'implementazione di un pattern Singleton nel codice Java è (a volte) considerata un anti-pattern nel mondo Java?
risposta
Testing
Un motivo è che single non sono facili da maneggiare con test di unità. Non è possibile controllare l'istanziazione e per la loro stessa natura può mantenere lo stato tra le invocazioni.
Per questo motivo il principio di dependency injection è popolare. Ogni classe viene iniettata (configurata) con le classi che devono funzionare (piuttosto che derivare tramite accessori singleton) e quindi i test possono controllare quali istanze di classe dipendente utilizzare (e fornire mock se necessario).
Framework come Spring controllano il ciclo di vita dei loro oggetti e spesso creano singleton, ma questi oggetti vengono iniettati dai loro oggetti dipendenti dal framework. Pertanto, il codebase stesso non tratta gli oggetti come singleton.
ad es. piuttosto che questo (per esempio)
public class Portfolio {
private Calculator calc = Calculator.getCalculator();
}
si dovrebbe iniettare la calcolatrice:
public class Portfolio {
public Portfolio(Calculator c) {
this.calc = c;
}
}
Così l'oggetto Portfolio
Non sa/cura su come esistono molte istanze del Calculator
. I test possono iniettare un dummy Calculator
che rende facile il test.
Concurrency
Limitando a voi stessi di un'istanza di un oggetto, le opzioni per filettare sono limitati. L'accesso all'oggetto singleton può dover essere sorvegliato (ad esempio tramite sincronizzazione). Se è possibile mantenere più istanze di tali oggetti, è possibile adattare il numero di istanze ai thread in esecuzione e aumentare le capacità simultanee della base di codice.
Quindi, come fanno le persone che usano i singleton a "Testare" e " "Concurrency"? – Pacerier
Con qualche difficoltà. Strumenti come PowerMock possono fornire metodi per sovrascrivere i metodi singleton, ma sono strumenti complessi che fanno ricorso alla manipolazione bytecode –
La mia opinione personale è che viola il principio della responsabilità unica. Gli oggetti Singleton sono responsabili sia del loro scopo sia del controllo del numero di istanze prodotte che penso sia sbagliato.
Questo è il motivo per cui molte persone delegano il controllo a un oggetto di fabbrica.
Penso che ciò renda sospetto [l'interpretazione di] SRP. –
In che modo sospetti? – MikePatel
Sospettoso in quanto ciò chiaramente non è una cosa che non va nei Singletons, ma l'interpretazione di SRP indica che lo è. SRP (o questa interpretazione di esso) sembrerebbe essere il colpevole. –
Ci sono molti requisiti che si potrebbe avere sul Singleton:
- inizializzazione differita;
- smaltimento adeguato;
- ambito (uno per thread, ad esempio).
In genere, anche, avrete un sacco di single nella vostra app, e il Singleton modello non consente codice riutilizzabile. Quindi, se vuoi attuare tutte queste preoccupazioni per tutti i tuoi singleton, vedrai immediatamente la sua qualità anti-pattern.
I singleton come tali non sono necessariamente un anti-pattern, ma hanno solo pochi vantaggi e diventano un antipattern quando vengono utilizzati in modo errato (cosa che accade spesso).
Spesso, i singleton non sono affatto singleton, ma "variabili globali mascherate". Inoltre, spesso vengono utilizzati quando la proprietà "solo una istanza" non è in realtà un vantaggio. (che di nuovo è bilanciato dal fatto che molte volte l'implementazione è sbagliata allo stesso tempo).
In aggiunta a ciò, possono essere difficili da implementare con il multithreading in mente (spesso fatto in modo errato o inefficiente) e perdono la maggior parte dei loro benefici se si desidera controllare la loro istanziazione.
Se si desidera avere il controllo dell'istanziazione, è necessario farlo manualmente a un certo punto all'inizio del programma, ma si potrebbe anche semplicemente creare un'istanza di un oggetto normale e inoltrarla in seguito.
Se l'ordine di distruzione è di qualche preoccupazione, è necessario implementarlo manualmente. Un singolo oggetto automatico nella funzione principale è tanto più semplice e pulito.
[Mutevole] Singleton è un anti-pattern di un anti-pattern.
Il significativo anti-pattern sottostante è lo stato globale (o stato dell'ambiente). Con lo stato globale hai un grande blog di dipendenza attraverso il tuo programma. Ciò influisce sul testing, ma questa è solo una parte delle conseguenze di una cattiva programmazione.
Stratificato su questo, Singleton aggiunge un livello di complessità completamente superfluo semplicemente dichiarando i campi modificabili static
.
i campi soffrono dello stesso esatto problema, è lo stato globale. Non riesco a vedere come usare i campi statici sia meglio di un singleton. Qualche informazione a riguardo? –
@JuanMendes Come ho già detto, le statiche mutevoli sono meglio della statica mutabile singleton perché non hanno la complessità inutile. –
Dovrei rivedere le risposte meglio prima di lasciare un commento. Il 100% è d'accordo con te. È fondamentalmente un eufemismo per lo stato globale, quindi chiamarlo come campi statici almeno non tenta di abbellirlo. –
Strano. Sembra che l'implementazione errata di un Singleton sia un "anti-pattern", non lo stesso Singleton.
Penso che abbiamo dimenticato che ogni programma deve iniziare da qualche parte. Deve esserci un'implementazione concreta di ogni astrazione, e alla fine ogni dipendenza sarà risolta, o la tua app non sarebbe molto utile.
La maggior parte dei framework DI consente di creare un'istanza di una classe come Singleton, la gestisce solo per te. Se si sceglie di fare da soli, l'iniezione di un singleton non è un problema. Anche Singleton IS è testabile e, se stai usando DI per iniettarlo, non rende instabile una classe.
IMO, come ogni altro modello là fuori (compresi DI e IoC) è uno strumento. A volte si adatta, a volte no.
- 1. proprietà Perché definiscono nel prototipo è considerato un antipattern
- 2. Esiste un equivalente API Web ASP.NET nel mondo JAVA?
- 3. Perché il codice Java rallenta nel debugger?
- 4. La convalida dei campi sia nel costruttore che nel setter è considerata un codice ridondante errato?
- 5. Compilando java nel codice nativo?
- 6. Perché questo codice è 100 volte più lento nel debug?
- 7. File di origine Java "generati meccanicamente" nel codice sorgente Java
- 8. Java: c'è qualche motivo per verificare se un singleton è nullo due volte?
- 9. Come vengono implementate le applicazioni Java nel "mondo reale"?
- 10. Come istanziare un Singleton più volte?
- 11. ORM nel mondo reale
- 12. Traduzione di C# RSACryptoServiceProvider nel codice JAVA
- 13. Java: stringa di scansione per un pattern
- 14. Java EE applicazioni open source nel mondo reale
- 15. Glassfish nel mondo reale
- 16. Perché la sizeof è considerata un operatore?
- 17. esegue un nuovo codice java nel processo jvm esistente
- 18. È un OutputStream nel blocco di Java? (Prese)
- 19. Pattern di strategia composita - java - Quanto è pericoloso questo codice?
- 20. Come scrivere un Java Singleton EE/EJB Java?
- 21. Perché questo comportamento è consentito nel modello di memoria Java?
- 22. "loop:" nel codice Java. Cos'è questo, perché lo compila?
- 23. android (modifica la stringa nel codice java)
- 24. Posso compilare Java nel codice nativo?
- 25. Cosa significa suffisso "f" nel codice Java?
- 26. java Singleton esemplificazione
- 27. MVC in un mondo Java di Google App Engine
- 28. Cosa significa "m" nel codice java
- 29. Qual è lo scopo dell'annotazione @param nel codice Java?
- 30. classe singleton in Java API
possibile duplicato di [Singleton Design Pattern: Pitfalls] (http://stackoverflow.com/questions/1448393/singleton-design-pattern-pitfalls) – msw