Domanda

Mi dispiace se si tratta di un duplicato o troppo elementare, ma come faccio a creare una classe singleton che può essere sottoclassata?

È stato utile?

Soluzione

Steve Yegge ha un divertente articolo sui singoli che menziona la sottoclasse in questa citazione :

  

Poi c'è la cosa della sottoclasse.   È quasi impossibile sottoclassare a   Singleton, e se lo gestisci, allora   non avresti dovuto usare a   Singleton in primo luogo. tu   non nemmeno andare lì. Io ho   camminavo su strade che non oso raccontare.   Fai solo finta di non poterlo fare, e   ti risparmierai quantità incredibili   di dolore.

Altri suggerimenti

In genere non puoi, in alcun senso utile. Questa sarebbe un'altra ragione per non usare le classi Singleton.

In realtà, non credo sia possibile.

Puoi creare una classe singleton dichiarando i suoi costruttori come private . Ma se poi provi a dichiarare una sottoclasse della tua classe singleton, il costruttore delle sottoclassi non sarà in grado di vedere i costruttori della superclasse ... in modo che non vengano compilati; per es.

public class A () {
    private A() { }
}

public class B () {
    private B() { }
}

Sia il compilatore Sun JDK 1.6 che Eclipse Ganymede generano un errore di compilazione nel costruttore B, per cui il costruttore no-args per A non è visibile.

Potresti aumentare la visibilità dei costruttori private , ma poi non c'è nulla (a parte il buon senso) che impedisce a qualcuno di crearne più istanze. In altre parole, in realtà non è più una lezione singleton.

EDIT: immagino che un'alternativa kosher sarebbe quella di definire un albero di una o più classi astratte (non singleton) con i metodi / membri che si desidera essere comuni, quindi definire più classi singleton come classi foglia come adeguata. Ma quella NON è una classe singleton che ne subclassa un'altra.

Se hai definito il tuo singleton come:

public class Singleton {
  private static Singleton instance;
  public static Singleton getInstance() {
     if (instance == null) {
       instance = new Singleton();
     }
     return instance;
  }
  private Singleton() {
  }
}

Quindi puoi semplicemente fare:

public class NewSingleton extends Singleton {
}

Ma non sarai in grado di usare i metodi privati, quindi se vuoi usare il singleton dovrai comunque chiamare Singleton.getInstance (); in modo da non ottenere nulla estendendolo .

Ma non c'è motivo per cui non puoi farlo.

Ora, se si desidera aggiungere più funzioni alla classe Singleton, è possibile utilizzare aspetti tra i tipi da AspectJ e iniettare nuovi metodi / proprietà in Singleton che potrebbero essere utilizzati da Singleton.

Singleton limita le istanze non l'ereditarietà. Bene - come già sottolineato, limita l'utilità dell'eredità e quindi puoi rilassare il costruttore privato in pacchetti o protetti (che potresti sostenere diminuisce la singolarità del singleton) Ma qual è lo scopo?

Come altri hanno già risposto, gli usi della sottoclasse di singleton sono piccoli. Se è necessario un modello di strategia nel contesto di un singleton, è possibile definire un'interfaccia e delegare a un'implementazione di tale interfaccia nell'istanza singleton. Questo sposta il problema di un livello verso il basso e rende più chiaro il motivo per cui vorresti farlo.

Per rispondere alla tua domanda; supponendo che la scelta per la particolare sottoclasse utilizzata dall'applicazione sia definita, ad esempio, nelle proprietà del sistema, puoi fare qualcosa del tipo:

public static synchronised Singleton getInstance() {
    if (instance == null) {
        String clsName = System.getProperties().getProperty("singleton.class");
        if (className == null || 0 == clasName.length()) {
            instance = new Singleton();
        } else {
            Class cls = Class.forName(clsName);
            instance = (Singleton) cls.newInstance();
        }
     }
     return instance;
}

Dichiarazione di non responsabilità: codice non testato, aggiunta gestione eccezioni, ecc .:-) A proposito, assicurati che il tuo metodo getInstance () sia sincronizzato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top