Паттерн "Посредник"

2017-07-02 • edited 2021-02-06

Паттерн “Посредник” (Mediator1 )

Содержание

Введение Необходимость паттерна “Посредник” возникает

  • Когда нужно реализовать взаимодействие между объектами, которые не должны знать о существовании друг друга.

Существует 2 основных варианта этого паттерна:

  1. Взаимодействующие объекты знают о медиаторе, медиатор может знать или не знать о медиаторе.

  2. Медиатор знает о существовании всех объектов, объекты ничего не знают.

Ниже представлена UML-диаграмма данного паттерна.

stragUml

Синхронизация информации между агентами.

В данном примере воспользуемся паттерном “Медиатор” для синхронизации информации между агентами. Реализуем самый простой вариант этого паттерна, когда объекты и медиатор знают друг о друге.

Реализации

**C#**

Класс-агент. Ему известно о медиаторе _hq.

class Agent
{
    private List<string> _intel = new List<string>();
    private Hq _hq;
    private readonly string _name;

    private string GetGeneratedIntel()
    {
        return $"Secret intel: {Guid.NewGuid().GetHashCode()}";
    }

    public void RecieveIntel(string intel)
    {
        _intel.Add(intel);
    }

    public void SyncIntel()
    {
        var intel = GetGeneratedIntel();
        _intel.Add(intel);

        _hq.SendIntelToAllAgents(this, intel);
    }

    public string GetTotalIntel()
    {
        return $"{_name}\n{_intel.Aggregate((f,s)=> $"{f}\n{s}")}";
    }

    public Agent(Hq hq, string name)
    {
        _name = name;
        _hq = hq;
    }
}

Класс-медиатор. Он знает обо всех агентах и синхронизирует их состояние. Агенты, однако, не знают друг о друге.

class Hq
{
    private List<Agent> _agents = new List<Agent>();

    public Hq()
    {
        _agents.AddRange(
            new List<Agent>()
            {
                new Agent(this, "Joe"),
                new Agent(this, "Smith"),
                new Agent(this, "Roberto"),
                new Agent(this, "Cherry"),
                new Agent(this, "Razor"),
                new Agent(this, "Blade"),
                new Agent(this, "Gustav"),
                new Agent(this, "Petya")
            }
            );
    }

    public void SendIntelToAllAgents(Agent sender, string intel)
    {
        foreach(var agent in _agents.Where(a=> a!= sender))
        {
            agent.RecieveIntel(intel);
        }
    }

    public void CheckAgents()
    {
        foreach (var agent in _agents)
        {
            agent.SyncIntel();
        }
    }

    public string GetTotalIntel()
    {
        return _agents.Select(a => a.GetTotalIntel()).Aggregate((f, s) => $"{f}\n{s}");
    }
}

Используем реализованную функциональность.

class Program
{
    static void Main(string[] args)
    {
        var hq = new Hq()

        for (var i = 0; i < 10; i++)
        {
            hq.CheckAgents();
        }        

        Console.WriteLine(hq.GetTotalIntel());
    }
}

Весь код использованный в проекте доступен на GitHub .

Литература

[1]: Mediator pattern from Wiki [2]: Тепляков С. Паттерны проектирования на платформе .NET – СПб.: Питер, 2015. — 57-68 c. [3]: Design Patterns: Elements of Reusable Object-Oriented Software

design patternCsharpповеденческий шаблонbehavioralmediatorпосредник
License: MIT

Паттерн "Посетитель"

Паттерн "Итератор"

comments powered by Disqus