Comment puis-je faire en sorte que d'autres classes dérivent d'une classe singleton?

StackOverflow https://stackoverflow.com/questions/1605083

  •  05-07-2019
  •  | 
  •  

Question

Je suis désolé s'il s'agit d'un doublon ou d'un élément trop élémentaire, mais comment puis-je créer une classe singleton pouvant être sous-classée?

Était-ce utile?

La solution

Steve Yegge a publié un article à propos de singletons qui mentionne les sous-classes dans cette citation. :

  

Ensuite, il y a le sous-classement.   Il est presque impossible de sous-classer un   Singleton, et si vous le gérez, alors   vous n'auriez pas dû utiliser un   Singleton en premier lieu. Vous   ne pas même vouloir y aller. J'ai   des chemins parcourus que je n'ose pas raconter.   Fais comme si tu ne pouvais pas le faire, et   vous économiserez des quantités incroyables   de la douleur.

Autres conseils

Vous ne pouvez généralement pas, dans un sens utile. Ce serait encore une autre raison de ne pas utiliser les classes Singleton.

En fait, je ne pense pas que ce soit possible.

Vous créez un singleton de classe en déclarant que son ou ses constructeurs sont private . Mais si vous essayez ensuite de déclarer une sous-classe de votre classe singleton, le constructeur des sous-classes ne pourra pas voir les constructeurs de la super-classe ... afin qu'ils ne compilent pas. par exemple

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

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

Les compilateurs Sun JDK 1.6 et Eclipse Ganymede génèrent une erreur de compilation dans le constructeur B, indiquant que le constructeur no-args pour A n’est pas visible.

Vous pouvez augmenter la visibilité des constructeurs private , mais il n'y a alors rien (sauf le bon sens) qui empêche quelqu'un de créer plusieurs instances de celui-ci. En d’autres termes, ce n’est plus vraiment une classe de singleton.

EDIT: Je suppose qu’une alternative casher consisterait à définir une arborescence d’une ou plusieurs classes abstraites (non singleton) avec les méthodes / membres que vous souhaitez utiliser en commun, puis à définir plusieurs classes singleton en tant que classes feuille approprié. Mais ce n’est PAS une classe de singleton en sous-classant une autre.

Si vous avez défini votre singleton comme suit:

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

Ensuite, vous pouvez simplement faire:

public class NewSingleton extends Singleton {
}

Mais, vous ne pourrez pas utiliser les méthodes privées, donc si vous voulez utiliser le singleton, vous devrez toujours appeler Singleton.getInstance (); afin de ne rien gagner en l'étendant. .

Mais, il n'y a aucune raison pour que vous ne puissiez pas le faire.

Maintenant, si vous souhaitez ajouter plus de fonctions à la classe Singleton, vous pouvez utiliser les aspects inter-types de AspectJ et simplement injecter de nouvelles méthodes / propriétés dans le Singleton, qui pourraient ensuite être utilisées par le Singleton.

Singleton limite les instances et non l'héritage. Comme cela a déjà été dit, cela limite l’utilité de l’héritage et vous pouvez alors assouplir un constructeur privé pour qu’il soit emballé ou protégé (ce qui, selon vous, diminue l’unicité du singleton). Mais quel est le but?

Comme d’autres l’ont déjà répondu, les utilisations des sous-classes de singleton sont faibles. Si vous avez besoin d'un modèle de stratégie dans le contexte d'un singleton, vous pouvez définir une interface et déléguer une implémentation de cette interface dans l'instance de singleton. Cela déplace le problème d’une couche vers le bas et explique plus clairement pourquoi vous voulez le faire.

Pour répondre à votre question. En supposant que le choix de la sous-classe particulière utilisée par votre application soit défini, par exemple, dans les propriétés système, vous pouvez effectuer quelque chose comme:

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;
}

Clause de non-responsabilité: code non testé, ajout de la gestion des exceptions, etc. :-) Par ailleurs, assurez-vous que votre méthode getInstance () est synchronisée.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top