Přidej si svou IT školu do profilu a najdi spolužáky zde na síti :)

Mediator

Návrh Návrhové vzory GOF Vzory chování Mediator

ONEbit hosting Unicorn College Tento obsah je dostupný zdarma v rámci projektu IT lidem. Vydávání, hosting a aktualizace umožňují jeho sponzoři.

Návrhový vzor Mediator zavádí "prostředníka" mezi přímou komunikaci několika objektů. Tím snižuje počet vazeb mezi objekty a reguluje jejich odpovědnost. Jedná se o velice populární princip, který využívá i vzor Controller ze sady vzorů GRASP, případně vzor Indirection rovněž z GRASP.

Motivace

Ačkoli to zní možná paradoxně, přidáním "umělé" třídy můžeme často naši aplikaci zjednodušit. Pokud spolu nějaká množina objektů komunikuje přímo, vzniká zbytečné množství složitých vazeb mezi nimi. Pokud bude množina objektů komunikovat pouze s mediátorem a on s nimi, sníží se počet těchto vazeb. Ukažme si, jak by mohla vypadat situace, kdyby spolu nějaké komponenty komunikovaly přímo:

Vazby mezi objekty bez aplikování vzoru Mediátor

Množství vazeb mezi komponentami je vysoké, porušujeme low coupling a komponenty na sobě navzájem závisejí. Nyní zkusme zavést prostředníka, který bude veškerou komunikaci zprostředkovávat:

Vazby mezi objekty po aplikování vzoru Mediátor

Mediátor rovněž sníží potřebu přesné znalosti objektů mezi sebou a kód se zjednoduší. Stačí, když objekt umí komunikovat jen s mediátorem. O nic dalšího se nemusí starat. Komunikační mechanismus mezi objekty poté zůstane zapouzdřený na jednom místě, v mediátoru. Objekty lze takto samozřejmě i jednoduše měnit bez nutnosti úpravy všech dalších účastníků interakce.

V praxi se mediátor často používá např. pro komunikaci mezi formulářovými prvky. Zabráníme tím, aby se na sebe musely formulářové prvky navzájem odkazovat, budou komunikovat s mediátorem, samostatným objektem, který bude podle aktuálních akcí upravovat stav formuláře.

Vzor

Vzor Mediator zavádí několik pojmů:

  • Mediator - Pro mediátor definuje abstraktní třídu. Konkrétních mediátorů může být poté více.
  • Colleague - Abstraktní třídu poté definuje rovněž pro kolegy, objekty v interakci. Díky abstraktní třídě mohou konkrétní kolegové rovnou jednoduše zdědit vazbu na mediátor.
  • ConcreteColle­ague... - Konkrétní objekty implementují libovolné operace a mají vazbu na mediátor.
  • ConcreteMedia­tor... - Konkrétní mediátory udržují vazbu na všechny kolegy, aby mohly komunikaci zprostředkovávat.
Návrhový vzor Mediátor z GOF

Příklad

Poměrně klasickým příkladem pro použití vzoru je vytvoření mediátoru pro různé typy loggerů. Aplikace potom nekomunikuje s několika loggery, ale s jedním mediátorem, který podle metod a parametrů zprostředkovává komunikaci na loggery. Toto použití mediátoru je velmi podobné fasádám, ovšem s tím rozdílem, že fasáda často pouze deleguje na rozhraní nějaké již existující implementace, zatímco prostředník v sobě obsahuje logiku, kód potřebný pro zprostředkování komunikace.

Takový složený mediátor pro logování by mohl vypadat např. takto:

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 pomocí nějaké vnitřní logiky deleguje logování na různé loggery. Ukažme si ještě rozdíl oproti fasádě nad loggery, která by rozhraní pouze delegovala:

public class LoggerFacade {

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

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

Související vzory

  • Fasáda - Delegování funkcionality pomocí jednoduchého rozhraní na skupinu dalších objektů

 

 

Článek pro vás napsal David Čápka
Avatar
Jak se ti líbí článek?
Ještě nikdo nehodnotil, buď první!
Autor pracuje jako softwarový architekt a pedagog na projektu ITnetwork.cz (a jeho zahraničních verzích). Velmi si váží svobody podnikání v naší zemi a věří, že když se člověk neštítí práce, tak dokáže úplně cokoli.
Unicorn College Autor se informační technologie naučil na Unicorn College - prestižní soukromé vysoké škole IT a ekonomie.
Miniatura
Předchozí článek
Interpreter
Miniatura
Všechny články v sekci
GOF - Vzory chování
Miniatura
Následující článek
Iterator
Aktivity (1)

 

 

Komentáře

Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zatím nikdo nevložil komentář - buď první!