2009-12-31 3 views
0

J'ai réfléchi à la meilleure façon d'implémenter un certain type de fonctionnalité ... étant des objets dérivés référençant d'autres objets dérivés avec la même base (y compris le référencement mutuel). Ci-dessous, le meilleur exemple (simple) que je puisse imaginer pour illustrer le genre de problème: une maison composée de 3 pièces (bien qu'en pratique elle pourrait être des centaines) chacune représentée par sa propre classe dérivée. Bien sûr cela ne fonctionnera pas tel quel, cela provoquerait un débordement de pile (de manière appropriée!)Suggérer un modèle de design?

En supposant que chaque pièce de l'exemple est spécifique à une pièce d'une maison imaginaire, il ne devrait pas y avoir plus d'une instance de toute sous-classe. Construire beaucoup d'instances, même sans la récursivité, serait désordonné. Cela me ferait penser à un singleton si ce n'était pas un tabou ... quelqu'un peut-il suggérer quelque chose de plus approprié?

Merci!

public abstract class Room 
{ 
    abstract public void DoAction(); 
    public Room[] ConnectedRooms; 
} 

public class Kitchen : Room 
{ 
    public Kitchen() { ConnectedRooms = new Room[] { new Hall() }; } 
    public override void DoAction() { MakeTea(); } 
} 

public class Bedroom : Room 
{ 
    public Bedroom() { ConnectedRooms = new Room[] { new Hall() }; } 
    public override void DoAction() { Sleep(); } 
} 

public class Hall : Room 
{ 
    public Hall() { ConnectedRooms = new Room[] { new Hall(), new Bedroom() }; } 
    public override void DoAction() { LookOutWindow(); } 
} 
+0

Je ne recommanderais pas singleton ici juste pour appliquer l'exigence d'instance unique. Il est vraiment difficile de recommander quoi que ce soit sans en savoir plus sur ce que vous faites. Parfois, le meilleur motif de conception n'est pas un motif de conception. Mieux vaut savoir quand ne pas utiliser un motif que celui à utiliser. –

+0

Le constructeur de Hall est-il censé installer les pièces connectées dans une autre salle ou dans la cuisine? –

Répondre

4

Vos chambres doivent contenir références à une instance de l'autre pièces - pas de nouvelles instances.

par exemple. créez un nouveau Kitchen, Hall, Bedroom. Puis passez une référence du Hall au Bedroom, au Kitchen etc. De cette façon vous avez vos trois objets, et ils ont des références aux pièces voisines.

Kitchen k = new Kitchen(); 
Bedroom b = new Bedroom(); 
k.addNeighbour(b); 

etc.

(normalement je construis un Kitchen avec des références appropriées, mais vous semblez avoir des références circulaires, de sorte que ce n'est pas si facile)

Si vous avez vraiment besoin seulement une instance de chacun, puis consultez le singleton pattern. Cependant, je ne le ferais pas à moins que cela ne soit strictement nécessaire. Après tout, beaucoup de maisons ont plus d'une chambre à coucher!

+0

Mes pensées exactement. Je ne pense pas qu'un singleton soit approprié ici non plus, puisque vous voudrez probablement plusieurs instances de certains types de pièces ... Même si vous ne l'avez pas fait, cela ajoutera simplement de la complexité qui n'est pas nécessaire. –

+0

L'idée est bonne, créer toutes les pièces une fois et tenir la référence pour les connexions au lieu de créer chaque pièce plusieurs fois. –

+0

Merci c'est intéressant, même si cela nécessiterait de déplacer la définition de connexion de la définition de classe ... ce qui, je suppose, a des avantages et des inconvénients. Dans la définition de la classe, il serait facile de trouver où les connexions de la classe ont été définies. Cependant, avoir toutes les connexions définies dans un endroit a aussi des mérites. – Bobbins

0

Tout ce que vous devez faire est d'éviter d'instancier une pièce dans le constructeur d'une autre. Vous aurez besoin d'instancier toutes vos pièces (Cuisine k = nouvelle cuisine(), Hall h = nouvelle Hall();), puis ajoutez les connexions (k.ConnectedRooms [0] = h; h.ConnectedRooms [0] = k;). Ou, pour être intelligent, créer une méthode qui les relie mutuellement:

public abstract class Room 
{ 
public void Connect(Room r) 
{ 
this.ConnectedRooms.Add(r); 
r.ConnectedRooms.Add(this); 
} 
} 

En supposant que vous modifiez vos tableaux de connexion à des listes, ce qui est probablement une bonne idée.

2

Vous avez vraiment besoin d'encapsuler (est-ce le bon mot?) Votre modèle plus loin.

public class House 
{ 
    private readonly Hall hall = new Hall(); 
    private readonly Kitchen kitchen = new Kitchen(); 

    // etc 

    public House() 
    { 
     hall.AddAdjacentRoom(kitchen); 
     // etc 
    } 

} 
+0

Joliment mis, une classe de maison relierait vraiment les salles ensemble. – Bobbins

Questions connexes