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).

Č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ť