Каков наилучший шаблон для двустороннего общения между классами? - PullRequest
5 голосов
/ 14 декабря 2010

У меня есть классы, которые должны общаться друг с другом. Проблема в том, что если вы сделаете так, чтобы одно содержало другое (отношения родитель-потомок), то все становится хитро Вам либо нужно передать экземпляр родительского объекта дочернему элементу (затем какой из них вы создадите первым, если вы используете внедрение зависимостей), или вы можете использовать делегаты / события. Но я хочу обеспечить тот факт, что родитель должен иметь возможность обрабатывать событие, которое вызывает ребенок. Не слишком уверен, как это сделать. Я также не хочу нескольких подписчиков на событие.

Отношения между родителями и детьми просто кажутся неправильными для двустороннего общения. К сожалению, это не тот случай, когда один из объектов всегда инициирует, а другой отвечает. Каждый может инициировать, а другой должен ответить.

Есть ли другой шаблон, который мне не хватает?

UPDATE: Извините, это довольно сложно объяснить. Я забыл добавить, что когда один класс отправляет сообщение другому, он не ожидает немедленного ответа. Ответ поступает асинхронно, поэтому вам необходим экземпляр родительского элемента для вызова правильного метода или делегат / событие. Извините, пример ниже - псевдокод. Надеюсь, этого достаточно, чтобы понять. Должен ли я посмотреть на образец посредника.

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

Ответы [ 5 ]

2 голосов
/ 14 декабря 2010

Сложно дать хороший ответ, поскольку ваш вопрос немного абстрактен. Но как насчет паттерна Mediator ?

1 голос
/ 14 декабря 2010

Сделать промежуточный объект, содержащий подробности связи, и ввести его как в A, так и в B?

1 голос
/ 14 декабря 2010

Может быть, вам стоит использовать загрузчик:

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

Теперь и А, и Б, блаженно не знают друг друга.

0 голосов
/ 14 декабря 2010

Это пример, также может быть сделано с использованием интерфейсов.

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 голосов
/ 14 декабря 2010

Возможно, вы захотите взглянуть на шаблон событий домена и пример кода от Udi Dahan.Он имеет тот же основной принцип, что и фрагмент кода, размещенный Чадом. Мартин Фаулер также написал о паттерне и предоставляет немного больше информации по теме.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...