Monostate vs Singleton

Quels sont les scénarios où l'on utiliserait un modèle Monostate au lieu de singleton inorder pour maintenir un objet global?

Modifier: Je sais ce que sont les modèles Singleton et Monostate. Ont également mis en œuvre Singleton dans un certain nombre de scénarios. Je veux juste connaître les scénarios (exemples de cas) où le modèle MonoState doit être implémenté.

Pour par exemple. J'ai besoin de maintenir la liste des colonnes par écran dans mon application Windows forms. Je pourrais utiliser un dictionnaire Singleton dans ce cas. Cependant, Je stocke une liste dans la var globale statique et je voulais fournir des indexeurs (puisque je dois ajouter dynamiquement une nouvelle entrée à la liste si la clé n'est pas présente) où je pourrais spécifier ScreenDetails.ScreenName comme clé et obtenir les ScreenDetails.ColumnsTable. Puisque les indexeurs ne peuvent pas fonctionner sur une classe statique, j'ai changé le modèle en Monostate.

Donc, j'aimerais savoir quels autres scénarios peuvent obliger un utilisateur à utiliser Monostate au lieu de Singletons.

44
demandé sur Rashmi Pandit 2009-05-20 15:04:24

5 réponses

À sa base, le monostate est juste du sucre syntaxique autour de Singleton. Lorsque Monostate devient intéressant, c'est lorsque vous commencez à sous-classer, car les sous-classes peuvent décorer l'état partagé avec un comportement différent.

Un simple -- si quelque peu artificiel et pas très efficace:) -- exemple:

public class GlobalTable implements Iterable<Key> {

  /** Shared state -- private */    
  private static final Map<Key, Value> MAP = new LinkedHashMap<Key, Value>();

  /** Public final accessor */    
  public final Value get(Key key) {
    return MAP.get(key);
  }

  /** Public final accessor */    
  public final boolean put(Key key, Value value) {
    return MAP.put(key);
  }

  /** Protected final accessor -- subclasses can use this to access
      the internal shared state */    
  protected final Set<Key> keySet() {
    return MAP.keySet();
  }

  /** Virtual -- subclasses can override for different behavior */    
  public Iterator<Key> iterator() {
    return Collections.unmodifiableSet(MAP.keySet()).iterator();
  }
}

Maintenant, que faire si nous voulons un accès indexé?

public class IndexedGlobalTable extends GlobalTable {

  public List<Key> getKeysAsList() {
    return Collections.unmodifiableList(new ArrayList<Key>(keySet()));
  }

  public Key getKeyAt(int index) {
    return getKeysAsList().get(index);
  }

  public Value getValueAt(int index) {
    return get(getKeyAt(index));
  }
}

Que diriez-vous des clés triées?

public class SortedGlobalTable extends GlobalTable {

  @Override
  public Iterator <Key> iterator() {
    return Collections
      .unmodifiableSortedSet(new TreeSet<Key>(keySet())).iterator();
  }

}

Chaque fois que vous avez besoin de l'une ou l'autre vue des données, vous instanciez simplement la vue appropriée sous-classe.

Bien sûr, si les données globales sont vraiment une bonne idée en premier lieu est une autre question, mais au moins Monostate vous donne plus de flexibilité dans la façon dont vous l'utilisez.

17
répondu David Moles 2013-08-27 18:59:25

Monostate et singleton sont deux visages d'une même médaille (état global):

  • monostate force un comportement (une seule valeur sur toutes les instances de classe)
  • singleton force une contrainte structurelle (une seule instance)

L'utilisation de Singleton n'est pas transparente

C'est-à-dire:

Singleton singleton = Singleton.getInstance();

L'utilisation du Monostat est transparente

C'est-à-dire:

MonoState m1 = new MonoState();
MonoState m2 = new MonoState(); // same state of m1 
66
répondu dfa 2009-05-20 11:23:49

Voici ce que Robert C. Martin a à dire à ce sujet: Singleton vs Monostate (pdf)

SINGLETON est mieux utilisé lorsque vous avez une classe existante que vous voulez contraindre par dérivation, et cela ne vous dérange pas que tout le monde devra appeler l'instance() méthode pour gagner l'accès. Monostate est mieux utilisé lorsque vous voulez la nature singulière de la la classe doit être transparente pour les utilisateurs, ou lorsque vous souhaitez utiliser des dérivés polymorphes de la simple objet.

40
répondu egaga 2018-02-08 07:46:01

Quelqu'un devrait juste noter que singletons et monostate sont des modèles extrêmement dangereux. Ils ont tendance à être mal utilisés par les codeurs paresseux qui ne veulent pas avoir à penser à la durée de vie de l'objet qu'ils veulent transformer en singleton. Ils rendent les tests plus difficiles et créent des systèmes rigides qui sont étroitement liés.

Il est extrêmement rare de trouver une situation où un singleton ou un monostate est vraiment nécessaire. La méthode préférée de collaboration d'objet est L'Injection de dépendance.

Beaucoup a été écrit à ce sujet:

8
répondu Ed Sykes 2017-05-23 12:34:17

La différence entre les deux modèles est celle du comportement par rapport à la structure. Le modèle SINGLETON impose la structure de la singularité. Il empêche la création de plus d'une instance. Alors que MONOSTATE impose le comportement de la singularité sans imposer de contraintes structurelles.

Avantages du SINGLETON

  • Applicable à toute classe. Vous pouvez changer n'importe quelle classe en SINGLETON simplement en rendant ses constructeurs privés et par ajout des fonctions statiques appropriées et variable.
  • peut être créé par dérivation. Étant donné une classe, vous pouvez créer un sous-classe qui est un SINGLETON.
  • évaluation paresseuse. Si le SINGLETON n'est jamais utilisé, il n'est jamais créé.

Coûts du SINGLETON

  • La Destruction n'est pas définie. Il n'y a pas de bon moyen de détruire ou désactiver un SINGLETON. Si vous ajoutez une méthode decommission qui annule l'instance, d'autres modules du système peut-être encore la tenue d'une référence à L'instance SINGLETON. Les appels suivants à L'Instance provoqueront la création d'une autre instance, provoquant l'existence de deux instances simultanées.

  • Pas hérité. Une classe dérivée d'un SINGLETON n'est pas un singleton. Si elle doit être un SINGLETON, la fonction statique et la variable ont besoin pour y être ajouté.

  • De l'Efficacité. Chaque appel à L'Instance appelle l'instruction if. Pour la plupart des de ces appels, l'instruction if est inutile.

  • Non transparent. Les utilisateurs D'un SINGLETON savent qu'ils utilisent un SINGLETON car ils doivent appeler la méthode D'Instance.

Avantages de MONOSTATE

  • De la Transparence. Les utilisateurs D'un MONOSTAT ne se comportent pas différemment de les utilisateurs d'un objet normal. Les utilisateurs n'ont pas besoin de savoir que la l'objet est MONOSTATE.

  • Dérivabilité. Les dérivés D'un MONOSTATE sont des MONOSTATES. En effet, tous les les dérivés de MONOSTATE font partie du même MONOSTATE. Ils tous partagent les mêmes variables statiques.

  • Le Polymorphisme. Puisque les méthodes D'un MONOSTATE ne sont pas statiques, elles peut être remplacé dans un dérivé. Ainsi différents dérivés peuvent offrir un comportement différent sur le même ensemble de variables statiques.

  • Création et destruction bien définies. Les variables d'un MONOSTATE, être statique, ont des temps de création et de destruction bien définis.

Coûts de MONOSTATE

  • Pas de conversion. Une classe normale ne peut pas être convertie en un MONOSTATE classe par dérivation.

  • De l'Efficacité. Un MONOSTAT peut passer par de nombreuses créations et destructions parce que c'est un objet réel. Ces opérations sont souvent coûteux.

  • Présence. Les variables d'un MONOSTAT prennent de la place, même si MONOSTATE n'est jamais utilisé.

Développement de logiciels agiles, principes, modèles et pratiques Robert C. Martin

1
répondu Mohammad Akbari 2018-05-16 12:22:07