Návrhové vzory Java (design patterns): Mediator

Dnes sa pozrieme na ďalší návrhový vzor Mediator (java design patterns) z kategórie vzorov správania (behavioral patterns). Návrhové vzory v tejto kategórii sa zaoberajú komunikáciou (interaction) medzi objektami a ich zodpovednosťou (responsibility).

Návrhové vzory Java: Mediator (design pattern)
Návrhové vzory Java: Mediator (design pattern)

V článku sa dozvieš:

    Čo je návrhový vzor Mediator?

    Návrhový vzor Mediator (sprostredkovateľ) sa používa na zjednodušenie komunikácie medzi objektami v systéme tým, že ako centrálny bod zabezpečuje komunikáciu medzi objektami. Mediator zohráva rolu sprostredkovateľa a zabezpečuje, že objekty nekomunikujú priamo, čo udržiava systém ľahko rozšíriteľný a udržiavateľný.

    Aký problém návrhový vzor Mediator rieši?

    Problém, ktorý rieši, spočíva v tom, že pri komplexných systémoch môže byť vzájomná komunikácia medzi objektami zložitá a nejasná. S počtom tried alebo objektov narastá komplexnosť vzájomných vzťahov Cieľom tohto vzoru je zabezpečiť, aby sa objekty navzájom nepoznali a teda nezáviseli na sebe a aby sa komunikácia medzi objektami neodohrávala priamo, ale cez jednotného sprostredkovateľa (mediátora). Týmto spôsobom sa minimalizuje vzájomné viazanie objektov a uľahčuje sa zmena alebo pridávanie nových vzťahov, keďže všetky komunikácie prebiehajú cez sprostredkovateľa.

    Príklad Mediator implementácie v Jave

    To ako návrhový vzor Mediator (prostredník) dokáže zjednodušiť komunikáciu medzi objektami a odbúrať nadbytočné závislostí medzi nimi, si predvedieme teraz pri naprogramovaní jednoduchého chatu, ktorí umožňuje vzájomnú komunikáciu medzi účastníkmi diskusie prostredníctvom verejných aj súkromných správ.

    Mediator.java

    package designpatterns;
    
    public interface Mediator {
        void poslatSpravu(Diskuter od, String sprava);
        void poslatSukromnuSpravu(Diskuter odkoho, Diskuter komu, String sprava);
    }

    Rozhranie Mediator definuje metódy na posielanie správ všetkým účastníkom diskusie a posielanie súkromných správ konkrétnemu účastníkovi.

    Chat.java

    package designpatterns;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class Chat implements Mediator {
        private List<Diskuter> diskutujuci;
    
        public Chat() {
            this.diskutujuci = new ArrayList<>();
        }
    
        public void pridat(Diskuter diskuter) {
            diskutujuci.add(diskuter);
        }
    
        @Override
        public void poslatSpravu(Diskuter od, String sprava) {
            for(Diskuter prijmatel : diskutujuci) {
                // Poslanie správy všetkým okrem odosielateľa.
                if(prijmatel != od) {
                    prijmatel.prijatSpravu(sprava);
                }
            }
        }
    
        @Override
        public void poslatSukromnuSpravu(Diskuter od, Diskuter komu, String sprava) {
            for(Diskuter prijmatel : diskutujuci) {
                // Poslanie správy konkrétnemu príjmateľovi.
                if(prijmatel == komu) {
                    prijmatel.prijatSukromnuSpravu(od, sprava);
                }
            }
        }
    }

    Trieda Chat poskytuje implementáciu rozhrania Mediator. Obsahuje zoznam diskutujúcich a zabezpečuje, aby sa správy posielali buď všetkým účastníkom alebo konkrétnym osobám.

    Diskuter.java

    package designpatterns;
    
    public interface Diskuter {
        void poslatSpravu(String sprava);
        void prijatSpravu(String sprava);
        void poslatSukromnuSpravu(Diskuter komu, String sprava);
        void prijatSukromnuSpravu(Diskuter odkoho, String sprava);
    }

    Rozhranie Diskuter definuje metódy na posielanie a prijímanie verejných aj súkromných správ.

    Clen.java

    package designpatterns;
    
    public class Clen implements Diskuter {
        private String meno;
        private Chat chat;
    
        public Clen(String meno, Chat chat) {
            this.meno = meno;
            this.chat = chat;
            chat.pridat(this);
        }
    
        @Override
        public void poslatSpravu(String sprava) {
            System.out.println(meno + " posiela správu: " + sprava);
            chat.poslatSpravu(this, sprava);
        }
    
        @Override
        public void prijatSpravu(String sprava) {
            System.out.println(meno + " prijal/a správu: " + sprava);
        }
    
        @Override
        public void poslatSukromnuSpravu(Diskuter komu, String sprava) {
            System.out.println(meno + " posiela súkromnú správu: " + sprava);
            chat.poslatSukromnuSpravu(this, komu, sprava);
        }
    
        @Override
        public void prijatSukromnuSpravu(Diskuter odkoho, String sprava) {
            System.out.println(meno + " prijal/a súkromnú správu: " + sprava);
        }
    }

    Trieda Clen (člen) implementuje rozhranie Diskuter. Každý člen diskusie má meno a chat, do ktorého je pridaný. Môže posielať správy všetkým, prijímať správy a posielať súkromné správy.

    Main.java

    import designpatterns.Chat;
    import designpatterns.Clen;
    import designpatterns.Diskuter;
    
    public class Main {
        public static void main(String[] args) {
            Chat chat = new Chat();
            Diskuter clen1 = new Clen("Jozef", chat);
            Diskuter clen2 = new Clen("Petra", chat);
            Diskuter clen3 = new Clen("Dominik", chat);
            Diskuter clen4 = new Clen("Karolina", chat);
            clen1.poslatSpravu("Ahoj všetci!");
            clen4.poslatSukromnuSpravu(clen1, "Ahoj Jozef!");
            clen3.poslatSpravu("Idete si zahrať stolný futbal?");
            clen1.poslatSpravu("Jasné, prečo nie.");
            clen2.poslatSpravu("Mám prácu, ale jednu si zahrám.");
            clen4.poslatSpravu("Ja sa pridám.");
            clen3.poslatSpravu("Za minútku dole.");
            clen2.poslatSukromnuSpravu(clen1, "Vyklepeme ich ako rezne :-D");
        }
    }

    Hlavná trieda Main vytvára objekt chatu a pridá doňho niekoľko členov diskusie. Potom predvádza funkčnosť chatu – vzájomnú komunikáciu medzi členmi, ako posielanie a prijímanie správ vrátane súkromných správ.

    Medzi objektami (členmi diskusie) neexistujú pevné prepojenia, celá komunikácia prebieha prostredníctvom sprostredkovateľa – chatu. Pridávanie nových členov diskusie je rovnako jednoduché a navyše nezvyšuje komplexnosť komunikácie.

    Výstup z tohto príkladu je:

    Medzi objektami (členmi diskusie) neexistujú pevné prepojenia, celá komunikácia prebieha prostredníctvom sprostredkovateľa – chatu.

    Zhrnutie

    Návrhový vzor Mediator sa často používa, keď chceme prostredníctvom centralizovanej komunikácie dosiahnuť zjednodušenie v komunikácií a posielaní správ medzi objektami. Komplexnosť systému narastá s navýšením závislosti a vzťahov medzi objektami, tento návrhový vzor ich pomáha výrazne redukovať.

    Pripravili sme pre teba súbory so spomínaným príkladom vo forme kódu, ktorý si môžeš spustiť priamo v Jave. Stiahni si kód Java Mediator tu.

    Ak si Java programátor a hľadáš prácu, pozri si naše benefity pre zamestnancov a reaguj na najnovšie ponuky práce.

    O autorovi

    Jozef Wagner

    Java Developer Senior

    Viac ako 10 rokov programujem v Jave, momentálne pracujem v msg life Slovakia ako Java programátor senior a pomáham zákazníkom implementovať ich požiadavky do poistného softvéru Life Factory. Vo voľnom čase si rád oddýchnem v lese, prípadne si zahrám nejakú dobrú počítačovú hru.

    Daj nám o sebe vedieť