2010-12-14 3 views
5

J'ai des cours qui doivent communiquer entre eux. Le problème est que si vous faites l'un contenir l'autre (une relation parent-enfant) alors les choses deviennent difficiles. Vous devez soit passer une instance du parent dans l'enfant, (alors lequel créez-vous en premier si vous utilisez l'injection de dépendance) ou vous pouvez utiliser des délégués/événements. Mais je veux imposer le fait que le parent doit être capable de gérer l'événement que l'enfant soulève. Pas trop sûr de savoir comment faire ça. Je ne veux pas non plus de plusieurs abonnés à l'événement.Quel est le meilleur modèle pour la communication bidirectionnelle entre les classes?

La relation parent-enfant se sent juste mal pour la communication bidirectionnelle. Malheureusement, il ne s'agit pas d'un cas où l'un des objets initie toujours et l'autre répond. L'un peut initier et l'autre devrait répondre.

Y a-t-il un autre motif qui me manque?

MISE À JOUR: Désolé, c'est assez difficile à expliquer. J'ai oublié d'ajouter que lorsqu'un cours envoie un message à une autre classe, il n'attend pas la réponse immédiatement. La réponse arrive de manière asynchrone, ce qui explique pourquoi vous avez besoin d'une instance du parent pour appeler la bonne méthode ou d'un délégué/événement. Désolé l'exemple ci-dessous est un pseudo code. Espérons que c'est suffisant pour avoir l'idée. Dois-je regarder le modèle de médiateur.

public class Foo 
    { 
     public void SendMessageAToBar() 
     { 
      MessageA msg = new MessageA(); 
      Bar.ReceiveMessageAFromFoo(msg); 
     } 

     public void ReceiveMessageARespFromBar(MessageAResp msgResp) 
     { 
      //Got a response do something 
     } 

     public void ReceiveMessageBFromBar(MessageB msg) 
     { 
      //Do something msg 
      MessageBResp msgBResp = new MessageBResp(); 
      Bar.ReceiveMessageBRespFromFoo() 
     } 
    } 

    public class Bar 
    { 


     public void ReceiveMessageAFromFoo(MessageA msg) 
     { 
      //DO something. 
      MessageAResp resp = new MessageAResp(); 
      Foo.ReceiveMessageARespFromBar(resp); 
     } 

     public void SendMessageBToFoo() 
     { 
      MessageB msg = new MessageB(); 
      Foo.ReceiveMessageBFromBar(msg); 
     } 

     public void ReceiveMessageBRespFromFoo(MessageBResp msgResp) 
     { 
      //Got a response do something 
     } 
    } 
+0

Qu'est-ce qui différencie l'enfant de ce que vous ne voulez pas utiliser ici? –

+0

Pouvez-vous ajouter des exemples de code d'un enfant et d'un parent? – jgauffin

+0

Peut-être que cela vous aidera si vous décrivez les objets réels auxquels vous faites référence en tant que parents et enfants. Ce n'est pas toujours mauvais si l'enfant tient un ref aux parents. Il existe de nombreux cas comme TreeView, XmlNode etc, et l'utilisation d'un observateur est également une option très viable. Je ne sais pas pourquoi vous dites "Je ne veux pas non plus que plusieurs abonnés à l'événement". Pourriez-vous expliquer cela aussi? –

Répondre

2

Il est un peu difficile de fournir une bonne réponse, puisque votre question est un peu abstraite. Mais qu'en est-il du modèle Mediator?

+0

Je viens de tomber sur le motif Mediator. Je suis en train de regarder ça maintenant. :) – uriDium

1

Peut-être que vous devez utiliser un programme d'amorçage:

class Main 
{ 
    void Main(...) 
    { 
     A a = new A(); 
     B b = new B(); 

     a.MessagePosted += (sender, messageArgs) => b.ReadMessage(messageArgs.Message); 
     b.MessagePosted += (sender, messageArgs) => a.ReadMessage(messageArgs.Message); 
    } 
} 

Maintenant, A et B sont parfaitement inconscients les uns des autres.

+0

Aimez la syntaxe! –

0

Vous voudrez peut-être regarder l'exemple de code Domain Events Pattern et Udi Dahan. Il a le même principe de base à l'extrait de code publié par Chad. Martin Fowler a également écrit sur le modèle et fournit un peu plus d'informations sur le sujet.

0

Ceci est un exemple, peut également être fait en utilisant Interfaces.

public abstract class Attachable 
{ 
    public void Attach(Attachable attachable) 
    { 
     Attached = attachable; 
     attachable.Attach(this); 
    } 

    public Attachable Attached { get; private set; } 
    public abstract void DoSomethingUseful(object argument); 
} 


public class A : Attachable 
{ 
    #region Overrides of Attachable 

    public override void DoSomethingUseful(object argument) 
    { 
     // do something useful 
    } 

    #endregion 
} 

public class B : Attachable 
{ 
    #region Overrides of Attachable 

    public override void DoSomethingUseful(object argument) 
    { 
     // do something useful 

    } 

    #endregion 
} 

// Usage 
A a = new A(); 
B b = new B(); 
a.Attach(b); 
+0

Pas vraiment sûr de savoir comment cela fonctionnerait. Peux-tu élaborer? – uriDium

+0

Voir ma mise à jour (Usage). Chacun peut appeler DoSomethingUseful de l'autre (que vous changez pour votre but) et ils peuvent communiquer. – Aliostad

1

Créer un objet intermédiaire contenant des détails de communication et l'injecter dans A et B?

+0

Cela semble similaire au modèle de médiateur. Je n'ai pas encore fini de le lire. Vous permettra de savoir. – uriDium

+0

Oui, merci de l'avoir signalé.http://en.wikipedia.org/wiki/Mediator_pattern décrit à peu près votre cas. – Grozz

+0

Donc, sont "médiateur" et "bootstrapper" essentiellement les mêmes? – Chad

Questions connexes