Nom de l'considérations de conception pour choisir entre l'utilisation d'un singleton par rapport à une classe statique. En faisant cela, vous êtes en quelque sorte contraint de mettre en contraste les deux, donc quel que soit le contraste vous pouvez venir avec sont également utiles dans la démonstration de votre processus de pensée! Aussi, chaque enquêteur aime voir des exemples illustratifs. :)
Réponses
Trop de publicités?- Les Singletons peuvent implémenter des interfaces et hériter d'autres classes.
- Les Singletons peuvent être facilement chargées. Seulement quand il est nécessaire. C'est très pratique si l'initialisation comprend ressource coûteuse de chargement ou de connexions de base de données.
- Les Singletons offrir un objet réel.
- Les Singletons peut être étendue dans une usine. L'objet de gestion de derrière les scènes, c'est abstrait, il est donc préférable maintenable et les résultats dans un code de meilleure qualité.
Comment "éviter à la fois"? Les Singletons et les classes statiques:
- Peuvent introduire de l'état global
- Obtenir étroitement associée à plusieurs autres classes
- Masquer les dépendances
- Peut faire des tests unitaires de classes dans l'isolement difficile
Au lieu de cela, regarder dans l'Injection de Dépendance et d'Inversion de Contrôle Contenant les bibliothèques. Plusieurs de le Cio bibliothèques poignée de gestion de durée de vie pour vous.
(Comme toujours, il y a des exceptions, telle que les classes de mathématiques et de C# les méthodes d'extension.)
Je dirais la seule différence est la syntaxe: MySingleton.Actuel.Quelle que soit la (les) vs MySingleton.Quelle que soit la (les). L'état, comme David mentionné, est en fin de compte "statique" dans les deux cas.
EDIT: bury brigade est venu de digg ... de toute façon, j'ai pensé à une affaire qui aurait besoin d'un singleton. Les classes statiques ne peuvent pas hériter d'une classe de base, ni de mettre en œuvre une interface (au moins dans .Net ils ne peuvent pas). Donc, si vous avez besoin de cette fonctionnalité, vous devez utiliser un singleton.
L'un de mes préférés des discussions sur cette question est ici (site d'origine vers le bas, maintenant lié à l' Internet Archive Wayback Machine.)
Pour résumer les avantages de la flexibilité d'un Singleton:
- un Singleton peut être facilement converti dans une usine
- un Singleton peut être facilement modifié pour renvoyer différentes les sous-classes
- il peut en résulter une plus maintenable application
Une classe statique avec une charge de variables statiques est un peu un hack.
/**
* Grotty static semaphore
**/
public static class Ugly {
private static int count;
public synchronized static void increment(){
count++;
}
public synchronized static void decrement(){
count--;
if( count<0 ) {
count=0;
}
}
public synchronized static boolean isClear(){
return count==0;
}
}
Un singleton, avec un exemple, c'est mieux.
/**
* Grotty static semaphore
**/
public static class LessUgly {
private static LessUgly instance;
private int count;
private LessUgly(){
}
public static synchronized getInstance(){
if( instance==null){
instance = new LessUgly();
}
return instance;
}
public synchronized void increment(){
count++;
}
public synchronized void decrement(){
count--;
if( count<0 ) {
count=0;
}
}
public synchronized boolean isClear(){
return count==0;
}
}
L'état est dans l'instance.
Si le singleton peut être modifié plus tard pour faire de mise en commun, le fil-les instances locales, etc. Et aucun des déjà écrit, le code doit changer pour obtenir le bénéfice.
public static class LessUgly {
private static Hashtable<String,LessUgly> session;
private static FIFO<LessUgly> freePool = new FIFO<LessUgly>();
private static final POOL_SIZE=5;
private int count;
private LessUgly(){
}
public static synchronized getInstance(){
if( session==null){
session = new Hashtable<String,LessUgly>(POOL_SIZE);
for( int i=0; i < POOL_SIZE; i++){
LessUgly instance = new LessUgly();
freePool.add( instance)
}
}
LessUgly instance = session.get( Session.getSessionID());
if( instance == null){
instance = freePool.read();
}
if( instance==null){
// TODO search sessions for expired ones. Return spares to the freePool.
//FIXME took too long to write example in blog editor.
}
return instance;
}
Il est possible de faire quelque chose de similaire avec une classe statique, mais il y aura par appel les frais généraux indirects de l'expédition.
Vous pouvez obtenir de l'instance et de le transmettre à une fonction comme argument. Ce code permet d'être dirigé vers le "droit" de singleton. Nous savons que vous aurez seulement besoin d'elle... jusqu'à ce que vous n'avez pas.
Le gros avantage est que la dynamique des singletons peuvent être thread safe, alors qu'une classe statique ne peut pas, sauf si vous modifiez un caractère secret singleton.