Шаблон проектирования «Посредник» — это поведенческий шаблон проектирования, позволяющий определить отдельный компонент (посредник), управляющий взаимодействием между набором объектов. Посредник уменьшает зависимости между объектами и способствует ослаблению связи между ними.

Шаблон посредника полезен, когда у вас есть набор объектов, которым необходимо взаимодействовать друг с другом, и вы хотите отделить эти объекты друг от друга, чтобы уменьшить сложность их взаимодействия. Вместо того, чтобы каждый объект взаимодействовал напрямую с другими, объекты взаимодействуют с посредником, который затем взаимодействует с другими объектами от их имени. Это может упростить изменение взаимодействия между объектами, поскольку вам нужно изменить только посредник, а не сами объекты.

Допустим, вы организуете школьное мероприятие и хотите пригласить к участию различные группы. У вас есть группа студентов, которым интересно танцевать, группа студентов, которые хотят накрыть стол для творчества, и группа студентов, которые хотят провести научный эксперимент.

Чтобы помочь координировать различные группы и обеспечить бесперебойную работу мероприятия, вы можете выступить в роли посредника. Это означает, что вместо того, чтобы каждая группа напрямую общалась друг с другом о своих планах на мероприятие, они могут пройти через вас. Вы можете выслушать идеи каждой группы и убедиться, что потребности каждого учтены при планировании мероприятия.

Выступая в качестве посредника, вы можете помочь уменьшить конфликты и убедиться, что идеи каждого будут услышаны и включены в окончательный план. Это может облегчить совместную работу разных групп и внести свой вклад в мероприятие, а не вступать в разногласия или недоразумения.

using System;

namespace MediatorExample
{
    // The Mediator interface declares a method used by components to notify the
    // mediator about various events. The Mediator may react to these events and
    // pass the execution to other components.
    public interface IMediator
    {
        void SendMessage(string message, Colleague colleague);
    }

    // The ConcreteMediator class coordinates interactions between components by
    // sending messages between them.
    public class ConcreteMediator : IMediator
    {
        private Colleague1 _colleague1;
        private Colleague2 _colleague2;

        public ConcreteMediator(Colleague1 colleague1, Colleague2 colleague2)
        {
            this._colleague1 = colleague1;
            this._colleague1.SetMediator(this);
            this._colleague2 = colleague2;
            this._colleague2.SetMediator(this);
        }

        public void SendMessage(string message, Colleague colleague)
        {
            if (colleague == this._colleague1)
            {
                this._colleague2.ReceiveMessage(message);
            }
            else
            {
                this._colleague1.ReceiveMessage(message);
            }
        }
    }

    // The Colleague class declares a method used by the Mediator to send and
    // receive messages.
    public abstract class Colleague
    {
        protected IMediator _mediator;

        public Colleague(IMediator mediator)
        {
            this._mediator = mediator;
        }

        public void SetMediator(IMediator mediator)
        {
            this._mediator = mediator;
        }

        public abstract void SendMessage(string message);
        public abstract void ReceiveMessage(string message);
    }

    // Concrete Colleagues communicate with each other indirectly via the Mediator.
    public class Colleague1 : Colleague
    {
        public Colleague1(IMediator mediator) : base(mediator)
        {
        }

        public override void SendMessage(string message)
        {
            this._mediator.SendMessage(message, this);
        }

        public override void ReceiveMessage(string message)
        {
            Console.WriteLine("Colleague 1 received message: " + message);
        }
    }

    public class Colleague2 : Colleague
    {
        public Colleague2(IMediator mediator) : base(mediator)
        {
        }

        public override void SendMessage(string message)
        {
            this._mediator.SendMessage(message, this);
        }

        public override void ReceiveMessage(string message)
        {
            Console.WriteLine("Colleague 2 received message: " + message);
        }
    }
}

Интерфейс IMediator объявляет метод с именем SendMessage, который используется объектами Colleague для отправки сообщений друг другу. Класс ConcreteMediator реализует этот интерфейс и предоставляет конкретную логику того, как сообщения передаются между объектами Colleague.

Класс Colleague — это абстрактный базовый класс, определяющий интерфейс для связи с посредником. Он имеет два абстрактных метода: SendMessage и ReceiveMessage. Классы ConcreteColleague1 и ConcreteColleague2 являются конкретными реализациями класса Colleague и обеспечивают конкретную реализацию методов SendMessage и ReceiveMessage.

Когда объект Colleague хочет отправить сообщение другому объекту, он вызывает метод SendMessage для себя, который, в свою очередь, вызывает метод SendMessage для посредника. Затем посредник определяет, какой объект Colleague должен получить сообщение, и вызывает метод ReceiveMessage для этого объекта.

Затем вы можете использовать этот шаблон там, где хотите, как показано ниже:

class Program
{
    static void Main(string[] args)
    {
        // The client code.
        Colleague1 colleague1 = new Colleague1(new ConcreteMediator());
        Colleague2 colleague2 = new Colleague2(new ConcreteMediator());

        colleague1.SendMessage("Hello, world!");
        colleague2.SendMessage("Hi there!");
    }
}

В этом коде мы создаем два объекта Colleague, colleague1 и colleague2, и передаем объект ConcreteMediator каждому из их конструкторов. Затем мы используем метод SendMessage для каждого из объектов Colleague для отправки сообщений другому объекту. При отправке сообщения вызывается метод SendMessage объекта ConcreteMediator, который затем отправляет сообщение другому объекту Colleague.

Представьте, что вы создаете чат-приложение, которое позволяет пользователям отправлять сообщения друг другу. Вы хотите спроектировать приложение таким образом, чтобы пользовательские объекты были отделены друг от друга, чтобы вы могли добавлять или удалять пользователей из чата, не внося изменений в другие пользовательские объекты.

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

Вот как код для этого может выглядеть на C#:

using System;
using System.Collections.Generic;

namespace MediatorExample
{
    // The Mediator interface declares a method used by components to notify the
    // mediator about various events. The Mediator may react to these events and
    // pass the execution to other components.
    public interface IChatMediator
    {
        void SendMessage(string message, User sender);
        void AddUser(User user);
    }

    // The ConcreteMediator class coordinates interactions between components by
    // sending messages between them.
    public class ChatMediator : IChatMediator
    {
        private List<User> _users;

        public ChatMediator()
        {
            this._users = new List<User>();
        }

        public void SendMessage(string message, User sender)
        {
            foreach (User user in this._users)
            {
                if (user != sender)
                {
                    user.ReceiveMessage(message);
                }
            }
        }

        public void AddUser(User user)
        {
            this._users.Add(user);
        }
    }

    // The Colleague class declares a method used by the Mediator to send and
    // receive messages.
    public abstract class User
    {
        protected IChatMediator _mediator;

        public User(IChatMediator mediator)
        {
            this._mediator = mediator;
        }

        public void SendMessage(string message)
        {
            this._mediator.SendMessage(message, this);
        }

        public abstract void ReceiveMessage(string message);
    }

    // Concrete Colleagues communicate with each other indirectly via the Mediator.
    public class ChatUser : User
    {
        public ChatUser(IChatMediator mediator, string name) : base(mediator)
        {
            this.Name = name;
        }

        public string Name { get; set; }

        public override void ReceiveMessage(string message)
        {
            Console.WriteLine("{0} received message: {1}", this.Name, message);
        }
    }
}

Интерфейс IChatMediator объявляет метод с именем SendMessage, который используется объектами ChatUser для отправки сообщений друг другу. Класс ChatMediator реализует этот интерфейс и предоставляет конкретную логику того, как сообщения передаются между объектами ChatUser. Он также имеет метод AddUser для добавления новых пользователей в чат.

Класс User — это абстрактный базовый класс, определяющий интерфейс для связи с посредником. Он имеет единственный абстрактный метод с именем ReceiveMessage. Класс ChatUser является конкретной реализацией класса User и обеспечивает конкретную реализацию метода ReceiveMessage. Он также имеет свойство Name для идентификации пользователя.

Когда объект ChatUser хочет отправить сообщение другим пользователям, он вызывает метод SendMessage для себя, который, в свою очередь, вызывает метод SendMessage для посредника. Затем посредник отправляет сообщение всем объектам ChatUser, кроме отправителя. Каждый объект ChatUser получает сообщение, вызывая метод ReceiveMessage для самого себя.

Теперь вы готовы его использовать:

class Program
{
    static void Main(string[] args)
    {
        // The client code.
        IChatMediator mediator = new ChatMediator();

        ChatUser user1 = new ChatUser(mediator, "Alice");
        ChatUser user2 = new ChatUser(mediator, "Bob");
        ChatUser user3 = new ChatUser(mediator, "Charlie");

        mediator.AddUser(user1);
        mediator.AddUser(user2);
        mediator.AddUser(user3);

        user1.SendMessage("Hi, everyone!");
        user2.SendMessage("Hello, Alice!");
        user3.SendMessage("Hey, what's up?");
    }
}

В этом коде мы создаем объект ChatMediator и три объекта ChatUser. Мы добавляем объекты ChatUser к посреднику, а затем используем метод SendMessage для каждого из объектов ChatUser для отправки сообщений другим пользователям. При отправке сообщения вызывается метод SendMessage объекта ChatMediator, который затем отправляет сообщение другим объектам ChatUser.

Заключение

Шаблон проектирования посредника используется для обеспечения централизованного канала связи между объектами. Это позволяет объектам общаться друг с другом косвенно, через посредника, а не напрямую.

Использование шаблона медиатора имеет несколько преимуществ:

  1. Это снижает сложность объектов, устраняя необходимость в их прямых ссылках друг на друга. Это может облегчить добавление или удаление объектов из системы, так как их нужно только зарегистрировать у посредника.
  2. Это способствует слабой связи между объектами. Объектам не нужно знать о конкретных деталях реализации друг друга, им нужно знать только о посреднике и о том, как с ним общаться. Это может облегчить модификацию или расширение системы.
  3. Это может улучшить инкапсуляцию объектов, скрывая детали их связи друг от друга. Это может упростить изменение способа взаимодействия объектов, не влияя на их внутреннюю реализацию.
  4. Это может упростить добавление новых функций в систему. Если в систему необходимо добавить новый объект, его можно просто зарегистрировать у посредника и начать через него общение с другими объектами.

В целом, шаблон посредника может помочь упростить проектирование систем со многими объектами, предоставляя центральную точку связи между ними. Это может упростить добавление, удаление и изменение объектов в системе, а также улучшить инкапсуляцию и модульность объектов.

Вот несколько реальных сценариев, в которых шаблон проектирования посредника может быть полезен:

  1. Приложение чата. Как упоминалось в предыдущем примере, приложение чата может использовать шаблон посредника, чтобы пользователи могли отправлять сообщения друг другу. Посредник будет нести ответственность за пересылку сообщений соответствующим пользователям и обработку любых дополнительных функций, таких как ведение журнала или фильтрация.
  2. Система управления воздушным движением. Система управления воздушным движением может использовать шаблон посредника для координации движения самолетов в воздушном пространстве. Посредник будет нести ответственность за то, чтобы самолеты находились на безопасном расстоянии друг от друга, и за направление их к месту назначения.
  3. Сайт интернет-аукциона. Сайт интернет-аукциона может использовать шаблон посредника для облегчения общения между покупателями и продавцами. Посредник будет нести ответственность за управление процессом торгов и обеспечение того, чтобы соответствующие стороны были уведомлены о размещении заявки или продаже предмета.
  4. Компьютерная сеть. Компьютерная сеть может использовать шаблон посредника, чтобы позволить устройствам взаимодействовать друг с другом. Посредник будет отвечать за маршрутизацию сообщений между устройствами и обработку любых дополнительных функций, таких как безопасность или исправление ошибок.
  5. Платформа онлайн-игр. Платформа онлайн-игр может использовать шаблон посредника, чтобы позволить игрокам взаимодействовать друг с другом. Посредник будет отвечать за общение между игроками и облегчение игрового процесса.

Это всего лишь несколько примеров, но шаблон посредника может быть полезен в самых разных сценариях, где необходимо координировать взаимодействие между несколькими объектами.

Спасибо за прочтение! Если вы нашли статью полезной, вы можете аплодировать и подписаться. Так вы будете получать уведомления о новых статьях.

# Ссылка

Он был создан с помощью ChatGPT AI.