Mediator


V této části se podíváme na Mediator. Tento návrhový vzor usnadňuje komunikaci mezi různými komponentami.

Proč Mediator použít

U některých komponent, které mezi sebou komunikují nedává smysl aby mezi sebou měli přímé reference. Například když mohou do našeho systému kdykoliv vstoupit nebo z něj vystoupit. Když si například představíme nějakou chatovací místnost, tak namísto toho abychom uživatele mezi sebou různě propojovali je jen napojíme na nějakou centrální komponentu, která mezi nimi zprostředkovává komunikaci.

Příklad - Chatovací místnost

Následující ukázka ukazuje třídu ChatRoom a třídu Clovek. Třída ChatRoom představuje chatovací místnost a třída Clovek uživatele, kteří se k této místnosti mohou připojit a mohou mezi sebou komunikovat.

class Clovek {
    constructor(jmeno) {
        this.jmeno = jmeno;
        this.chatLog = [];
    }

    // tuto metodu může Mediator (chatovací místnost)
    // použít k poslání zprávy uživateli
    prijmi(odesilatel, zprava) {
        const text = `${odesilatel}: ${zprava}`;
        console.log(`[chat uživatele ${this.jmeno}] ${text}`);
        this.chatLog.push(text);
    }

    posli(zprava) {
        // poslání zprávy do chatovací místnosti
        this.room.broadcast(this.jmeno, zprava);
    }

    posliPrivatniZpravu(cil, zprava) {
        // poslání soukromé zprávy přes chatovací místnost
        this.room.zprava(this.jmeno, cil, zprava);
    }
}

// Mediator (chatovací místnost)
// - zajišťuje komunikaci mezi objekty třídy Clovek
class ChatRoom {
    constructor() {
        // v tomto poli jsou uloženi lidé, kteří
        // jsou k chatovací místnosti připojeni
        this.lide = [];
    }

    // tuto metodu mohou uživatelé použít k poslání
    // zprávy všem uživatelům v místnosti
    broadcast(zdroj, zprava) {
        for (let uzivatel of this.lide) {
            if (uzivatel.jmeno !== zdroj)
                uzivatel.prijmi(zdroj, zprava);
        }
    }

    // pomocí této metody se může uživatel
    // připojit k místnosti
    pripojit(uzivatel) {
        let zprava = `${uzivatel.jmeno} se připojil`;
        this.broadcast("room", zprava);

        uzivatel.room = this;
        this.lide.push(uzivatel);
    }

    // tuto metodu mohou uživatelé použít k poslání
    // soukromé zprávy nějakému uživateli
    zprava(zdroj, cil, zprava) {
        for (let uzivatel of this.lide) {
            if (uzivatel.jmeno === cil) {
                uzivatel.prijmi(zdroj, zprava);
                break;
            }
        }
    }
}


// vytvoření Mediatoru (chatovací místnosti)
const room = new ChatRoom();

const karel = new Clovek("Karel");
const pavel = new Clovek("Pavel");

// připojení lidí k chatovací místnosti
room.pripojit(karel);
room.pripojit(pavel);

// lidé mohou použít chatovací místnost k posílání zpráv
karel.posli("Zdravím");
pavel.posli("Zdar Karle");

const ivan = new Clovek("Ivan");

// připojení dalšího člověka do chatovací místnosti
room.pripojit(ivan);

// poslání zprávy
ivan.posli("Čau všichni");

// poslání soukromé zprávy od Karla Ivanovi
karel.posliPrivatniZpravu("Ivan", "Vítej Ivane");


// výsledný výstup bude takový:
// [chat uživatele Karel] room: Pavel se připojil
// [chat uživatele Pavel] Karel: Zdravím
// [chat uživatele Karel] Pavel: Zdar Karle
// [chat uživatele Karel] room: Ivan se připojil
// [chat uživatele Pavel] room: Ivan se připojil
// [chat uživatele Karel] Ivan: Čau všichni
// [chat uživatele Pavel] Ivan: Čau všichni
// [chat uživatele Ivan] Karel: Vítej Ivane