2010-12-14 13 views
5

Tengo clases que necesitan comunicarse entre sí. El problema es que si uno hace que el otro contenga el otro (una relación entre padres e hijos), entonces las cosas se vuelven complicadas. O bien debe pasar una instancia del padre al hijo, (entonces, ¿cuál creará primero si está usando la inyección de dependencia) o puede usar delegados/eventos? Pero quiero hacer cumplir el hecho de que el padre debe ser capaz de manejar el evento que el niño plantea. No estoy muy seguro de cómo hacer eso. Tampoco quiero múltiples suscriptores al evento.¿Cuál es el mejor patrón para la comunicación bidireccional entre clases?

La relación padre-hijo simplemente se siente mal para la comunicación bidireccional. Desafortunadamente no es un caso que uno de los objetos siempre inicie y el otro responda. Cualquiera puede iniciar y el otro debe responder.

¿Hay algún otro patrón que me falta?

ACTUALIZACIÓN: Lo siento, esto es bastante difícil de explicar. Olvidé agregar que cuando una clase envía un mensaje a otra clase, no espera la respuesta de inmediato. La respuesta viene de forma asíncrona, por lo que necesita una instancia del padre para llamar al método correcto o un delegado/evento. Lo siento, el siguiente ejemplo es pseudo código. Con suerte, es suficiente para tener la idea. Debería mirar el patrón del mediador.

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é tiene de diferente el niño, lo que significa que no quiere usar eventos aquí? –

+0

¿Puedes agregar ejemplos de código de un niño y un padre? – jgauffin

+0

Quizás te ayude si describes a qué objetos reales te refieres como padres e hijos. No siempre es malo si el niño tiene un ref como padre. Hay muchos casos como TreeView, XmlNode, etc. y también el uso de un Observer es una opción muy viable también. No estoy seguro de por qué está diciendo "Tampoco quiero múltiples suscriptores al evento". ¿Podrías explicar eso también? –

Respuesta

2

Es un poco difícil dar una buena respuesta, ya que su pregunta es un poco abstracta. Pero, ¿qué pasa con el patrón Mediator?

+0

Acabo de tropezar con el patrón Mediator. Estoy echando un vistazo a eso ahora. :) – uriDium

1

Tal vez se debe utilizar un programa previo:

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

Ahora, tanto A como B son felizmente inconscientes de la otra.

+0

¡Me encanta la sintaxis! –

0

Es posible que desee mirar el Domain Events Pattern y el código de muestra de Udi Dahan. Tiene el mismo principio básico que el fragmento de código publicado por Chad. Martin Fowler también ha escrito sobre el patrón y proporciona un poco más de información sobre el tema.

0

Este es un ejemplo, también se puede hacer utilizando 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

No estoy seguro de cómo funcionaría esto. ¿Puedes elaborar? – uriDium

+0

Ver mi actualización (Uso). Cada uno puede llamar a DoSomethingUseful del otro (que cambia para su propósito) y se pueden comunicar. – Aliostad

1

Haga un objeto intermedio que contenga los detalles de comunicación e inyéctelo tanto en A como en B?

+0

Eso parece similar al patrón del mediador. No he terminado de leerlo todavía. Te haré saber. – uriDium

+0

Sí, gracias por señalar eso.http://en.wikipedia.org/wiki/Mediator_pattern describe bastante su caso. – Grozz

+0

Entonces, ¿el "mediador" y el "iniciador" son básicamente iguales? – Chad

Cuestiones relacionadas