→ Пошук по сайту       Увійти / Зареєструватися
Знання Патерни Патерни поведінки — Behavioral patterns

17. Медіатор — Mediator

17.	Медіатор — Mediator

Я трохи думав над тим, який має бути приклад для Медіатора і мені на думку нічого кращого не спадало, ніж класичний приклад із взаємодією елементів в користувацькому інтерфейсі. Потім ще декілька варіантів прокрутилися, аж поки не спала на думку взаємодія нейронів. Я ще трохи подумав і в голову прийшла геніальна ідея (звичайно я не ручаюся, що більше такого прикладу немає, але мене осінило ним). Наш мозок є медіатором до різних частин тіла.

Мозок ідеально підходить під опис дизайн патерну Медіатор.

Просто спробуйте уявити, якби кожна із частин вашого тіла знала одна про іншу. Якщо б ваше око бачило щось приємне, то воно мало б знати, як напряму зв’язатися із ногами і змусити їх рухатися у заданому напрямку. Або якщо б вас хтось вдарив у живіт, ваш живіт повинен був би навчитися захищатися руками.

Живіт може й боліти, тоді він буде змушений знати про цілу систему м’язів, щоб змусити тіло прийняти розслаблююче положення. Взаємодія, описана вище, як багато-до-багатьох не є природньою для нашого тіла. Проте, чомусь, вона часто застосовна деякими програмістами до їхнього коду. Спочатку, поки програміст все пише по свіжому, такий код працює нормально, але із часом він перетворється на суцільне спагетті – безлад, в якому розібратися важко, а змінити поведінку, не поломавши чогось, також складно.

Наше тіло має одну центральну систему, яка аналізує прийняті сигнали і здійснює потрібні реакції. Це можна застосувати і до коду, який ми пишемо.

Медіатор централізує взаємодію між компонентами, таким чином послаблюючи їхню зв’язність.

Медіатор елегантно спрощує розуміння взаємодії між компонентами. Це полегшує підтримку коду у майбутньому, але, оскільки логіка централізована, вона може стати досить складною, зрештою чим наш мозок і є.

Нижче, наперед, наведемо консольний вивід, демонструючий приклад в дії:

 Enter body part (‘Ear’, ‘Eye’, ‘Hand’ or empty to exit):
Ear
Enter what you hear:
You are cool!
FACE: Smiling...
Enter body part (‘Ear’, ‘Eye’, ‘Hand’ or empty to exit):
Hand
What you feel is soft? (Yes/No)
Yeah!
What you feel is hurting? (Yes/No)
No
LEG: Stepping forward...
HAND: Embracing what is in front of you...
Enter body part (‘Ear’, ‘Eye’, ‘Hand’ or empty to exit):
Ear
Enter what you hear:
You are dumbass stupid guy!
LEG: Stepping forward...
HAND: Just hit offender...
LEG: Just kicked offender in front of you...
Enter body part (‘Ear’, ‘Eye’, ‘Hand’ or empty to exit):
Hand
What you feel is soft? (Yes/No)
No
What you feel is hurting? (Yes/No)
Yes
LEG: Stepping back...

Як видно, мозок знає як діяти в різних ситуаціях і які частини тіла слід задіяти. То як це відбувається?
Мозок (або новоспечений Медітор) знає про кожну частину тіла (colleague), а кожна частина тіла знає про мозок, тому може передавати сигнали йому та самій приймати їх. Звичайно, кожна частина тіла виконує ще й свою безпосередню функцію.

Уривок коду 17.1. Базовий клас для частин тіла сolleague (знає про мозок)

 class BodyPart
{
    private readonly Brain _brain;
    public BodyPart(Brain brain)
    {
        _brain = brain;
    }
    public void Changed()
    {
        _brain.SomethingHappenedToBodyPart(this);
    }
}

Уривок коду 17.2. Конкретна реалізація colleague може виглядати так

 class Ear : BodyPart
{
    private string _sounds = string.Empty;
    public Ear(Brain brain) : base(brain) { }

    public void HearSomething()
    {
        Console.WriteLine("Enter what you hear:");
        _sounds = Console.ReadLine();

        Changed();
    }
    public string GetSounds()
    {
        return _sounds;
    }
}

Як бачимо, вухо (Ear) може чути (HearSomething) і може передати звуки на аналіз мозку (GetSounds). Деякі чатини тіла мають іншу функціональність. Як, для прикладу, реалізація класу обличчя (Face):

Уривок коду 17.3. Обличчя

 class Face : BodyPart
{
    public Face(Brain brain)
        : base(brain)
    {
    }
    public void Smile()
    {
        Console.WriteLine("FACE: Smiling...");
    }
}

Як і слід було очікувати, клас медіатора є досить громіздким, оскільки він відповідає за «розрулювання» ситуації. Можливо, вам не сподобається те, як реалізовано цей конкретний мозок, але це не є аж на стільки важливо. Важливо зрозуміти як він діє.

Уривок коду 17.4. Мозок, або медіатор

 // Медіатор
class Brain
{
    public Brain()
    {
        CreateBodyParts();
    }

    private void CreateBodyParts()
    {
        Ear = new Ear(this);
        Eye = new Eye(this);
        Face = new Face(this);
        Hand = new Hand(this);
        Leg = new Leg(this);
    }

    public Ear Ear { get; private set; }
    public Eye Eye { get; private set; }
    public Face Face { get; private set; }
    public Hand Hand { get; private set; }
    public Leg Leg { get; private set; }

    public void SomethingHappenedToBodyPart(BodyPart bodyPart)
    {
        if (bodyPart is Ear)
        {
            string heardSounds = ((Ear)bodyPart).GetSounds();

            if (heardSounds.Contains("stupid"))
            {
                // Атакуємо образника
                Leg.StepForward();
                Hand.HitPersonNearYou();
                Leg.Kick();
            }
            else if (heardSounds.Contains("cool"))
            {
                Face.Smile();
            }
        }
        else if (bodyPart is Eye)
        {
            // Мозок може проаналізувати, що ви бачите і
            // прореагувати відповідно, використовуючи різні частини тіла
        }
        else if (bodyPart is Hand)
        {
            var hand = (Hand)bodyPart;

            bool hurtingFeeling = hand.DoesItHurt();
            if (hurtingFeeling)
            {
                Leg.StepBack();
            }

            bool itIsNice = hand.IsItNice();
            if (itIsNice)
            {
                Leg.StepForward();
                Hand.Embrace();
            }
        }
        else if (bodyPart is Leg)
        {
            // Якщо на ногу впаде цегла, змінюємо вираз обличчя 
        }
    }
}

Додаю трохи UML:

UML-діаграма 9. Медіатор

По матеріалам книги Андрія Будая "Дизайн патерни – просто, як двері". Матеріал розміщується за домовленістю з автором.
Робота представлена за умовами ліцензії Creative Commons Attribution-NonCommercial 3.0 Unported License.

загрузка...
Сторінки, близькі за змістом