Quando usare un Singleton e quando usare una classe statica [duplicato]

23

Ho cercato su questo qui e su StackOverflow e ho trovato alcune differenze tra i due.

Ma non sono ancora sicuro in quali casi si preferirebbe un Singleton, e in quali casi si sceglierebbe di usare una classe statica .

(Nelle lingue che non supportano le 'classi statiche', come Java, mi riferisco ovviamente alle classi che contengono solo metodi e campi statici).

Per favore, fornisci esempi concreti di casi in cui sceglieresti ciascuno e spiega perché.

    
posta Aviv Cohn 10.04.2014 - 15:29
fonte

3 risposte

24

Un caso in cui una classe statica potrebbe essere una buona idea è quando si desidera raccogliere parti correlate di funzionalità, ma non è necessario avere alcun stato interno in alcun oggetto. Un esempio potrebbe essere la classe Math in Java. Contiene un sacco di funzioni correlate a cui si accede al di fuori del contesto di qualsiasi istanza di oggetto specifica. Ho fatto cose simili in cui un insieme di funzioni di utilità comuni utilizzate in più punti di un'applicazione sono raggruppati in una singola classe di utilità.

Un singleton viene usato quando fai vuoi un oggetto reale (con il suo stato interno e tutto il resto), e vuoi limitare il tuo sistema a esattamente una istanza di quell'oggetto. Ciò potrebbe essere utile se si dispone di un tipo di risorsa condivisa, come un database, una cache in memoria o forse un pezzo di hardware specializzato come un braccio robotico. Molte parti del tuo programma potrebbero voler utilizzare questa risorsa e potresti voler far passare tutto l'accesso alla risorsa attraverso un singolo punto. Un singleton non è sempre il modo solo per gestire queste situazioni, ma è uno dei pochi luoghi in cui penso che potrebbe essere una buona scelta.

    
risposta data 10.04.2014 - 15:51
fonte
8
  • Evita lo schema di Gang of Four Singleton, per i motivi citati nelle altre risposte. Principalmente è un anti-pattern basato sulle difficoltà che crea per il test.

  • Factory and Dependency Injection ha reso Singleton obsoleto. La migliore risposta è usare una Fabbrica che decida se istanziare un'istanza, o molte, di una data classe. In questo modo, la classe e i suoi clienti non sono responsabili per il suo status di singleton - che diventa una preoccupazione trasparente gestita dalla Factory.

  • Quadri di iniezione delle dipendenze come Spring che ti fanno fuori dalla scatola (ad esempio i bean Spring sono singleton a meno che tu non specifichi diversamente).

  • Le classi puramente statiche sono problematiche sia per i test che per l'utilizzo di concetti OO. Ho visto squadre con un irresistibile bisogno di rendere tutto statico e definitivo, e la domanda diventa, perché non stanno solo scrivendo il codice C?

  • Se la tua classe statica ha effetti collaterali, non dovrebbe essere statica. Ciò significa che, se sta gestendo lo stato condiviso, o se sta cambiando lo stato dei parametri, dovrebbe essere una classe regolare in cui la Factory distribuisce un'unica istanza condivisa. Una classe puramente statica che gestisce lo stato condiviso diventa un problema davvero difficile da testare.

  • Una classe puramente statica crea anche dipendenze in fase di compilazione su quella particolare classe , il che compromette davvero la capacità di estensione e la capacità di test del codice. Sembra che vorrai riservarlo per qualcosa di eterno e immutabile, senza effetti collaterali, come le formule matematiche.

Quindi la risposta è, non scrivere classi come singleton, ma piuttosto spostare quella decisione nella tua Factory. E in un linguaggio OO, le classi statiche mancano alcuni degli aspetti progettuali più importanti della lingua e complicano i test. Di nuovo, puoi usare le classi worker con una semantica specifica per raggrupparle e farle generare dal tuo Factory.

    
risposta data 10.04.2014 - 16:17
fonte
0

Oggetti singoli creati in modo che ci possa essere solo 1 istanza in un dato momento e può essere utilizzata a livello di applicazione.

Gli oggetti che gestiscono cose come i pool di connessioni sono un buon candidato per essere Singletons;

  • Vuoi solo 1 istanza nell'intera applicazione
  • devi poterlo accedere da diverse parti dell'applicazione
  • i dati che contiene devono essere persistenti anche quando nessun altro oggetto lo sta attualmente puntando (utile quando si desidera riutilizzare oggetti che sono costosi da inizializzare).

Una classe riempita con solo metodi statici non è qualcosa che di solito è pensato per essere inizializzato come un oggetto. È più simile a un wrapper per i metodi statici in esso.

Un esempio di ciò che uso frequentemente è una classe di utilità con metodi che eseguono attività ripetitive che prendono parametri, esegue un calcolo con loro / formatta loro / etc. e quindi restituisce il risultato, senza utilizzare campi o metodi esterni (o almeno non statici). Non inizializzo mai una classe di utilità, utilizzo solo i metodi statici per tutti i metodi ripetitivi.

Questo è il modo in cui tendo ad usare le classi Singletons e statiche (con metodo), non sono sicuro che confermi gli standard "ufficiali" ...

    
risposta data 10.04.2014 - 15:57
fonte

Leggi altre domande sui tag