2010-12-14 10 views
5

Ho classi che devono comunicare tra loro. Il problema è che se ne fai uno contiene l'altro (una relazione genitore figlio), allora le cose si complicano. È necessario passare un'istanza del genitore nel figlio, (quindi quale si crea prima se si sta utilizzando l'iniezione di dipendenza) oppure è possibile utilizzare delegati/eventi. Ma voglio far rispettare il fatto che il genitore deve essere in grado di gestire l'evento che il bambino solleva. Non sei troppo sicuro di come farlo. Inoltre, non voglio più abbonati all'evento.Qual è lo schema migliore per la comunicazione bidirezionale tra le classi?

La relazione genitore-figlio è semplicemente sbagliata per la comunicazione bidirezionale. Sfortunatamente non è un caso che uno degli oggetti inizi sempre e l'altro risponda. O può iniziare e l'altro dovrebbe rispondere.

C'è un altro schema che mi manca?

AGGIORNAMENTO: Spiacente, questo è abbastanza difficile da spiegare. Ho dimenticato di aggiungere che quando una classe invia un messaggio a un'altra classe non si aspetta la risposta immediatamente. La risposta arriva in modo asincrono ed è per questo che hai bisogno di un'istanza del genitore per chiamare il metodo giusto o un delegato/evento. Spiacente, l'esempio qui sotto è pseudo codice. Spero sia abbastanza per avere l'idea. Dovrei guardare il modello di mediatore.

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

Cosa c'è di diverso nel bambino che significa che non vuoi usare gli eventi qui? –

+0

Puoi aggiungere esempi di codice di un bambino e un genitore? – jgauffin

+0

Forse sarà d'aiuto se descrivi quali oggetti reali ti riferisci come genitori e figli. Non è sempre male se il bambino possiede un riferimento al genitore. Ci sono molti casi come TreeView, XmlNode, ecc. E anche l'uso di un Observer è un'opzione molto valida. Non sei sicuro del motivo per cui stai dicendo "Inoltre, non voglio più abbonati all'evento". Potresti spiegarlo anche tu? –

risposta

2

È un po 'difficile fornire una buona risposta, poiché la domanda è un po' astratta. Ma, per quanto riguarda lo schema Mediator?

+0

Mi sono appena imbattuto nel modello di Mediatore. Sto dando un'occhiata a questo ora. :) – uriDium

1

Forse si dovrebbe utilizzare un programma di avvio automatico:

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); 
    } 
} 

Ora, sia A che B sono beatamente inconsapevoli l'uno dall'altro.

+0

Ama la sintassi! –

0

Si potrebbe voler guardare lo Domain Events Pattern e il codice di esempio da Udi Dahan. Ha lo stesso principio di base per lo snippet di codice pubblicato da Chad. Martin Fowler ha anche scritto sul modello e fornisce un po 'più di informazioni sull'argomento.

0

Questo è un esempio, anche può essere fatto utilizzando interfacce.

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

Non proprio sicuro di come funzionerebbe. Puoi elaborare? – uriDium

+0

Vedere il mio aggiornamento (utilizzo). Ognuno può chiamare l'altro DoSomethingUseful (che si modifica per il proprio scopo) e possono comunicare. – Aliostad

1

Creare un oggetto intermedio contenente dettagli di comunicazione e iniettarlo entrambi in A e B?

+0

Sembra simile al modello del mediatore. Non ho ancora finito di leggerlo. Le faremo sapere. – uriDium

+0

Sì, grazie per averlo indicato.http://en.wikipedia.org/wiki/Mediator_pattern descrive molto bene il tuo caso. – Grozz

+0

Quindi, "mediatore" e "bootstrapper" sono sostanzialmente gli stessi? – Chad

Problemi correlati