2011-12-02 18 views
6

Sto usando il driver java per MongoDB, e la documentazione dice a:Creazione di un riferimento statico contro un Singleton

"è necessario creare una singola istanza di Mongo, e si può usare in ogni richiesta."

L'utilizzo di una singola istanza suona come un singleton.

In altri posti per una libreria diversa ho letto le istruzioni dicendo che dovrei creare un riferimento statico dato che è thread-safe.

Qualcuno può spiegare le differenze tra un singleton e la creazione di un riferimento statico?

Così il codice vero e proprio che ho bisogno di istanziare in modo statico o tramite un Singleton sarebbe:

Mongo m = new Mongo("localhost" , 27017); 

qualcuno può spiegare entrambi i metodi e le differenze di fondo se del caso?

risposta

2

Singleton è un modello di progettazione in cui si dispone di un'istanza di un oggetto condiviso tra il resto del codice. Le variabili statiche sono una funzione della lingua Java .

Per implementare un Singleton, si utilizzano solitamente variabili statiche.

3

Hai 3 problemi: singleton, riferimento statico e thread-safety.

Si dispone di un singleton se è possibile creare solo un'istanza di una classe. È utile perché le cose si incasinano se hai due istanze di Mongo in esecuzione. Tuttavia, non è possibile implementare il modello di progettazione singleton per Mongo nel codice: è possibile chiamare new Mongo() ovunque si desideri e creare tutte le istanze desiderate. Devi solo fare attenzione a non farlo, ma non dovrebbe essere molto difficile.

Per implementare un Singleton, il progettista della classe sarà molto spesso utilizzare un riferimento statico come segue:

public class MyClass { 
    private static final MyClass SINGLETON = new MyClass(); 

    private MyClass() {...} // !!private, not accessible 

    public MyClass getSingleton() { return SINGLETON; } 
} 

e sarà sempre e solo avere una singola istanza del MyClass dal momento che il costruttore è privato e l'unico modo per ottenere un'istanza è attraverso MyClass.getSingleton(). Ovviamente il designer Mongo avrebbe dovuto progettare la classe Mongo come tale; non c'è niente che puoi fare per renderlo un singleton.

Per quanto riguarda la sicurezza del thread, non vedo il collegamento con singleton. Una classe singleton deve essere resa thread-safe: se molti thread cambiano e leggono lo stato di un singleton, è necessaria una sincronizzazione corretta per assicurarsi che tutti i thread vedano gli stessi valori. Non conosco Mongo, ma scommetto che è una lezione sicura per i thread.

+0

Mongo è thread-safe ed è dotato di un pool di connessioni, ho solo bisogno di creare una singola istanza di esso, quindi un'istanza statica è la strada da percorrere? – codecompleting

+2

@codecompleting Sì, da qualche parte nella tua classe principale che si occupa di Mongo dovresti avere 'statico finale privato Mongo mongo = new Mongo (" localhost ", 27017);' e assicurati di non creare un altro Mongo. Se hai un buon design di oggetti, le altre classi non accederanno mai a 'mongo' direttamente; se hai bisogno di altre classi per accedere a 'mongo', potresti fare un metodo' getMongo() 'nella tua classe principale. – toto2

0

Utilizzare il modello Singleton su un oggetto se si desidera passare solo una singola istanza di questo oggetto ad altri oggetti e metodi che devono utilizzare questa singola istanza. Utilizzare un riferimento statico se si desidera utilizzare la classe dell'oggetto solo staticamente (ovvero come riferimento statico).

0

Se solo una classe utilizza l'oggetto singleton non vi è alcuna differenza visibile nel numero di oggetti creati.

Se c'è bisogno di un oggetto di classASing usando approccio Singleton

ClassASing { 
    private static ClassASing obj = new ClassASing(); 
    private ClassAsing(){...} 
    public static ClassASing getNewObject(){ 
      return obj; 
    } 
} 

Utilizzando approccio Singleton

ClassB{ 
    private ClassASing singObj = ClassASing.getNewObject(); 
} 
  • non importa come molti casi di ClassB creato tutti loro saranno utilizzando lo stesso oggetto di ClassASing

utilizzando ref statico erenza

ClassB{ 
    private static ClassA sObj = new ClassA(); 
} 

* non importa come molti casi di ClassB creati tutti useranno lo stesso riferimento che punta allo stesso oggetto.

Non c'è molta differenza qui 1 oggetto utilizzato in entrambi i casi.

Ora se consideri un altro sencario che hai bisogno di un oggetto in due delle tue classi.

approccio Singleton

ClassB1{ 
      private ClassASing singObj1 = ClassASing.getNewObject(); 
     } 

ClassB2{ 
      private ClassASing singObj2 = ClassASing.getNewObject(); 
     } 
  • indipendentemente dal numero di istanze di ClassB1 creato tutti loro saranno utilizzando lo stesso oggetto di ClassASing
  • non importa come molti casi di ClassB2 creato tutti loro sarà utilizzando lo stesso oggetto ClassASing già utilizzato da ClassB1, quindi solo un oggetto di ClassASing

Approccio statico di riferimento

ClassB1{ 
    private static ClassA sObj1 = new ClassA(); 
} 

ClassB2{ 
    private static ClassA sObj2 = new ClassA(); 
} 
  • non importa quante istanze di ClassB1 creati tutti useranno lo stesso riferimento sobj1 indicando allo stesso oggetto
  • non importa come molti casi di ClassB2 creato tutti loro si utilizza il stesso riferimento sobj2 che punta allo stesso oggetto ma questo oggetto è diverso da quello creato in ClassB1 quindi ora hai due oggetti di ClassA.
+0

perdonami per gli errori di sintassi :) – Sudeep

Problemi correlati