2009-04-27 13 views
2

J'ai trois classes qui interagissent de manière intéressante. L'une est une classe modèle, et elle doit être accessible par les deux autres classes, donc une seule instance est conservée en tant que membre de chaque classe. Ces deux classes interagissent avec le modèle de différentes manières.Modèle partagé entre deux objets

Il existe deux cas où l'objet de modèle doit être complètement rejeté et remplacé par une nouvelle instance, ce qui complique les choses. Et ces occasions se présentent dans les deux classes de visualisation/contrôle. Ainsi, l'une ou l'autre de ces classes doit être capable d'envoyer un signal à l'autre en disant: "Nous devons coordonner et faciliter le remplacement de notre objet Modèle par un nouvel objet Modèle." En ce moment j'ai le code dans la classe B pour dire à la classe A de construire un nouveau modèle et de le renvoyer, mais maintenant je dois gérer la situation inverse, où l'événement survient dans la classe A, et malheureusement la classe A classe B et ne devrait probablement pas.

Quelle est une bonne façon de gérer cela?

Mise à jour: Désolé, les gens, cela ne peut pas être un singleton. Les singletons sont quand vous avez besoin de garantir qu'il y en a seulement un de quelque chose. Cela n'a rien à voir avec les exigences que j'ai exprimées ci-dessus. Cette classe n'est pas un singleton et ne devrait pas l'être. : Jusqu'à présent, il n'y avait qu'une seule instance de cette classe Model, mais j'avais un vague soupçon que je devais autoriser plus, et je ne voulais pas me limiter en utilisant le Singleton modèle de conception lorsque cela répond à des préoccupations différentes de ce que j'ai. Il se avère que j'avais raison: hier, j'ai reçu une nouvelle exigence et maintenant j'ai besoin de soutenir un nombre arbitraire de ceux-ci. :) Ne vous limitez pas lorsque vous n'avez pas à, et ne pas abuser des modèles de conception pour les situations où ils n'étaient pas destinés!

Répondre

5

Vous aurez besoin d'un calque de modèle intermédiaire, un objet "porteur" de modèle que chacune des deux classes référence. ModelHolder contient une référence au modèle.

Ce ModelHolder doit également prendre en charge les écouteurs. Ainsi, lorsque son modèle est rejeté, il peut avertir les écouteurs que le modèle a été modifié.

+0

Je suis entièrement d'accord. Le titulaire est le propriétaire du modèle. Il gère le cycle de vie du modèle, y compris les demandes de service des clients pour demander que le modèle soit remplacé par un nouveau. Les clients peuvent enregistrer un auditeur pour être informé des changements (comme un nouveau modèle). –

+0

Je pense que je vais avec une version modifiée de cela.ClassA est en fait le ModelHolder, donc j'ai juste implémenté une interface d'écoute que ClassB implémentera pour être averti quand il y aura un nouvel objet Model qu'il devrait récupérer. – skiphoppy

+0

hm. Hein? Pas besoin d'exposer les différents modèles réels! Laissez le SuperModel envoyer un "je suis mis à jour" à ses auditeurs, quand il a changé sa représentation interne. Comptez sur le fonctionnement de StatePattern. – KarlP

1

Ok, si vous avez besoin de changer le modèle (mais pas la force), vous pouvez faire une interface d'écoute, et faire les deux objets A et B mettent en œuvre:

public interface ModelListener { 

    public void modelChanged(Model newModel); 
} 

et au bon moment, vous pouvez informer les auditeurs du nouveau modèle changent. Vous pouvez également avoir une liste qui contient tous les écouteurs enregistrés.

List<ModelListener> modelListeners = new ArrayList<ModelListener>(); 

    public void setNewModel(Model m) { 
     for (ModelListener aListener : m.modelListeners) 
      aListener.modelChanged(m); 
    } 

Comme toujours, il existe des compromis entre la simplicité et la robustesse. Vous pourriez vouloir expérimenter avec les niveaux dont vous avez besoin pour votre propre cas.

+0

Je ne pense pas que cela fonctionnera; Je ne vois pas comment une méthode statique dans la classe Model peut diriger les instances de ClassA et ClassB pour remplacer le contenu de leur champ de modèle. – skiphoppy

+0

Le modèle n'est pas un singleton. – skiphoppy

+0

Pourquoi getNewModel() est-il synchronisé? –

0

Je rencontre souvent ce problème de conception dans les projets GUI (Swing, GWT). Ce que je fais habituellement est de créer un modèle "State" de plus haut niveau, qui contient une instance de l'objet qui est partagée entre deux ou plusieurs classes. State a ensuite une interface ModelListener, que les autres classes peuvent implémenter pour recevoir une notification des modifications apportées au modèle sous-jacent. State.setFoo() envoie ensuite les événements ModelChanged aux écouteurs, qui répondent en conséquence.

Questions connexes