Vianoce v ITnetwork sú tu! Dobí si teraz kredity a získaj až 80 % extra kreditov na e-learningové kurzy ZADARMO. Zisti viac.
Hľadáme nové posily do ITnetwork tímu. Pozri sa na voľné pozície a pridaj sa k najagilnejšej firme na trhu - Viac informácií.

Mediator

Návrhový vzor Mediator zavádza "sprostredkovateľa" medzi priamu komunikáciu viacerých objektov. Tým znižuje počet väzieb medzi objektmi a reguluje ich zodpovednosť. Jedná sa o veľmi populárny princíp, ktorý využíva aj vzor Controller zo sady vzorov GRASPO, prípadne vzor inDirection rovnako z GRASPO.

Motivácia

Hoci to znie možno paradoxne, pridaním "umelé" triedy môžeme často našu aplikáciu zjednodušiť. Ak spolu nejaká množina objektov komunikuje priamo, vzniká zbytočné množstvo zložitých väzieb medzi nimi. Pokiaľ bude množina objektov komunikovať iba s mediátorom a on s nimi, zníži sa počet týchto väzieb. Ukážme si, ako by mohla vyzerať situácia, keby spolu nejaké komponenty komunikovali priamo:

Väzby medzi objektmi bez aplikovania vzoru Mediátor - GOF - Vzory správania

Množstvo väzieb medzi komponentmi je vysoké, porušujeme low coupling a komponenty na sebe navzájom závisia. Teraz skúsme zaviesť prostredníka, ktorý bude všetku komunikáciu sprostredkovávať:

Väzby medzi objektmi po aplikovaní vzore Mediátor - GOF - Vzory správania

Mediátor takisto zníži potrebu presnej znalosti objektov medzi sebou a kód sa zjednoduší. Stačí, keď objekt vie komunikovať len s mediátorom. O nič ďalšie sa nemusí starať. Komunikačné mechanizmus medzi objektmi potom zostane zapuzdrený na jednom mieste, v mediátora. Objekty možno takto samozrejme aj jednoducho meniť bez nutnosti úpravy všetkých ďalších účastníkov interakcie.

V praxi sa mediátor často používa napr. Pre komunikáciu medzi formulárovými prvkami. Zabránime tým, aby sa na seba museli formulárové prvky navzájom odkazovať, budú komunikovať s mediátorom, samostatným objektom, ktorý bude podľa aktuálnych akcií upravovať stav formulára.

Vzor

Vzor Mediator zavádza niekoľko pojmov:

  • Mediator - Pre mediátor definuje abstraktné triedu. Konkrétnych mediátorov môže byť potom viac.
  • Colleague - Abstraktné triedu potom definuje tiež pre kolegov, objekty v interakcii. Vďaka abstraktné triede môžu konkrétne kolegovia rovno jednoducho zdediť väzbu na mediátor.
  • ConcreteColleague... - Konkrétne objekty implementujú ľubovoľné operácie a majú väzbu na mediátor.
  • ConcreteMediator... - Konkrétne mediátormi udržujú väzbu na všetkých kolegov, aby mohli komunikáciu sprostredkovávať.
Návrhový vzor Mediátor z GOF - GOF - Vzory správania

Príklad

Pomerne klasickým príkladom pre použitie vzoru je vytvorenie mediátora pre rôzne typy loggerov. Aplikácia potom nekomunikuje s niekoľkými loggery, ale s jedným mediátorom, ktorý podľa metód a parametrov sprostredkováva komunikáciu na loggery. Toto použitie mediátora je veľmi podobné fasádam, avšak s tým rozdielom, že fasáda často iba deleguje na rozhraní nejaké už existujúce implementácie, zatiaľ čo prostredník v sebe obsahuje logiku, kód potrebný pre sprostredkovanie komunikácie.

Taký zložený mediátor pre logovanie by mohol vyzerať napr. Nasledovne:

public class LoggerMediator {
    private TypLogovani typLogovani;
    private FileLogger fileLogger = new FileLogger();

    public void setTypLogovani(TypLogovani typLogovani) {
        this.typLogovani = typLogovani;
    }

    public void loguj(String zprava, Level level) {
        if (typLogovani == TypLogovani.Konzole) {
            if (level == Level.Error)
                System.err.println(zprava);
            else
                System.out.println(zprava);
        } else if (typLogovani == TypLogovani.Soubor) {
            if (level == Level.Error)
                fileLogger.log(zprava, FileLogger.ERROR);
            else
                fileLogger.log(zprava, FileLogger.DEBUG);
        }
    }
}

Mediátor pomocou nejakej vnútornej logiky deleguje logovanie na rôzne loggery. Ukážme si ešte rozdiel oproti fasáde nad loggery, ktorá by rozhranie iba delegovala:

public class LoggerFacade {

    public void logInfo(final String zprava) {
        System.out.println(zprava);
    }

    public void logError(final String zprava) {
        System.err.println(zprava);
    }
}

Súvisiace vzory

  • Fasáda - Delegovanie funkcionality pomocou jednoduchého rozhrania na skupinu ďalších objektov

 

Všetky články v sekcii
GOF - Vzory správania
Článok pre vás napísal David Hartinger
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
David je zakladatelem ITnetwork a programování se profesionálně věnuje 15 let. Má rád Nirvanu, nemovitosti a svobodu podnikání.
Unicorn university David sa informačné technológie naučil na Unicorn University - prestížnej súkromnej vysokej škole IT a ekonómie.
Aktivity