uriDium
uriDium

Reputation: 13420

What is the best pattern for two way communication between classes?

I have classes that need to communicate with each other. The problem is that if you make one contain the other (a child parent relationship) then things get tricky. You either need to pass an instance of the parent into the child, (then which one do you create first if you are using dependency injection) or you can use delegates/events. But I want to enforce the fact that the parent must be able to handle the event that the child raises. Not too sure how to do that. I also don't want multiple subscribers to the event.

The parent-child relationship just feels wrong for two way communication. Unfortunately it is not a case that one of the objects always initiates and the other responds. Either can initiate and the other should respond.

Is there another pattern that I am missing?

UPDATE: Sorry this is quite hard to explain. I forgot to add that when one class sends a message to another class it is not expecting the response immediately. The response comes in asynchronously which is why you either need an instance of the parent to call the right method or a delegate/event. Sorry the example below is pseudo code. Hopefully it is enough to get the idea. Should I look at the mediator pattern.

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

Upvotes: 5

Views: 4669

Answers (5)

Aliostad
Aliostad

Reputation: 81680

This is an example, also can be done using 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);

Upvotes: 0

Grozz
Grozz

Reputation: 8435

Make an intermediate object that contains communication details and inject it both in A and B?

Upvotes: 1

Frederik Gheysels
Frederik Gheysels

Reputation: 56944

It is a bit difficult to provide a good answer, since your question is a bit abstract. But, what about the Mediator pattern ?

Upvotes: 2

Kane
Kane

Reputation: 16812

You might want to look at the Domain Events Pattern and code sample by Udi Dahan. It is has the same basic principle to the code snippet posted by Chad. Martin Fowler has also written about the pattern and provides a little more information on the topic.

Upvotes: 0

Chad
Chad

Reputation: 3237

Maybe you should use a bootstrapper:

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

Now, both A and B are blissfully unaware of each other.

Upvotes: 1

Related Questions