Java programátor expert
Návrhové vzory Java (design patterns): Observer
Dnes sa pozrieme na ďalší návrhový vzor Observer (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 Observer?
Observer je návrhový vzor, ktorý nám umožňuje definovať mechanizmus odoberania správ a upozorňovanie všetkých zainteresovaných objektov na akékoľvek udalosti, ktoré nastanú na pozorovanom objekte.
Aký problém návrhový vzor Observer rieši?
Vzor Observer (Pozorovateľ) je návrhový vzor, ktorý rieši problém sledovania zmeny stavu objektu tak, aby všetky jeho závislé objekty (pozorovatelia) boli automaticky informované a aktualizované, keď sa vyskytne zmena v objekte. Tento vzor umožňuje vytvoriť slabé väzby medzi subjektom (objekt, ktorý mení svoj stav) a pozorovateľmi (objekty, ktoré chcú byť informované o zmene).
Pozorovaný objekt – vydavateľ (Publisher) prechádza udalosťami zaujímavými pre iné objekty. Tieto udalosti nastanú, keď zmení svoj stav alebo vykoná nejakú akciu. Vydavatelia obsahujú infraštruktúru predplatného, ktorá umožňuje novým predplatiteľom (Subscribers) pripojiť sa a súčasným predplatiteľom opustiť zoznam.
Keď nastane nová udalosť, vydavateľ prejde zoznam odberov a zavolá metódu upozornenia deklarovanú v rozhraní odberateľa na každom objekte odberateľa. Rozhranie predplatiteľa vo väčšine prípadov pozostáva z jedinej update metódy.
Metóda môže mať niekoľko parametrov, ktoré umožňujú vydavateľovi spolu s aktualizáciou informovať detailnejšie o udalosti. Konkrétni predplatitelia vykonávajú v reakcii na upozornenia vydané vydavateľom vlastné akcie.
Všetky tieto triedy musia implementovať rovnaké rozhranie, takže vydavateľ nie je priamo spojený s konkrétnymi triedami. Predplatitelia zvyčajne potrebujú kontextové informácie na správne spracovanie aktualizácie. Klient vytvorí objekty vydavateľa a predplatiteľa samostatne a potom zaregistruje predplatiteľov na aktualizácie vydavateľa.
Príklad Observer implementácie v Jave
Aby sme si ukázali praktické aplikovanie návrhového vzoru Observer, vytvoríme jednoduchú simuláciu YouTube kanála, kam sa môžu používatelia (odoberatelia) prihlásiť k odberu notifikácií o nových videách na tomto kanáli alebo svoj odber zrušiť.
IOdoberatel.java
package designpatterns;
public interface IOdoberatel {
void aktualizovat(String sprava);
}
Rozhranie IOdoberatel definuje metódu aktualizovat, ktorú budú konkrétni odoberatelia implementovať. Používa sa na aktualizáciu v prípade nového obsahu.
YouTubePouzivatel.java
package designpatterns;
public class YouTubePouzivatel implements IOdoberatel {
private String meno;
public YouTubePouzivatel(String meno) {
this.meno = meno;
}
@Override
public void aktualizovat(String videoTitul) {
System.out.println(meno + " dostal/a notifikáciu o novom videu: " + videoTi-tul);
}
@Override
public String toString() {
return meno;
}
}
Trieda YouTubePouzivatel reprezentuje konkrétneho používateľa, ktorý môže prijímať notifikácie o nových videách.
IYoutubeKanal.java
package designpatterns;
public interface IYoutubeKanal {
void odoberat(IOdoberatel odoberatel);
void zrusitOdber(IOdoberatel odoberatel);
void upozornitOdoberatelov(String videoTitul);
}
Rozhranie IYoutubeKanal definuje metódy odoberat, zrusitOdber a upozornitOdoberatelov, ktoré budú konkrétny YouTube kanál implementovať. Používa sa na správu odoberateľov.
YouTubeKanal.java
package designpatterns;
import java.util.ArrayList;
import java.util.List;
public class YouTubeKanal implements IYoutubeKanal {
private List<IOdoberatel> odoberatelia = new ArrayList<>();
private String nazovKanala;
public YouTubeKanal(String nazovKanala) {
this.nazovKanala = nazovKanala;
}
@Override
public void odoberat(IOdoberatel odoberatel) {
odoberatelia.add(odoberatel);
System.out.println(odoberatel + " odoberá " + nazovKanala);
}
@Override
public void zrusitOdber(IOdoberatel odoberatel) {
odoberatelia.remove(odoberatel);
System.out.println(odoberatel + " odhlásil/a odber " + nazovKanala);
}
@Override
public void upozornitOdoberatelov(String videoTitul) {
for(IOdoberatel odoberatel : odoberatelia) {
odoberatel.aktualizovat(videoTitul);
}
}
public void nahratNoveVideo(String videoTitul) {
System.out.println("Nové video bolo pridané: " + videoTitul);
upozornitOdoberatelov(videoTitul);
}
}
Trieda YouTubeKanal reprezentuje konkrétny YouTube kanál, ktorý môže prihlasovať a odhlasovať odoberateľov a notifikovať ich o nových videách.
Main.java
import designpatterns.IOdoberatel;
import designpatterns.IYoutubeKanal;
import designpatterns.YouTubeKanal;
import designpatterns.YouTubePouzivatel;
public class Main {
public static void main(String[] args) {
// Vytvorenie YouTube kanalu
YouTubeKanal youtubeKanal = new YouTubeKanal("[Programovanie v Jave]");
// Vytvorenie odoberatelov (subscribers)
IOdoberatel odoberatel1 = new YouTubePouzivatel("Subscriber1");
IOdoberatel odoberatel2 = new YouTubePouzivatel("Subscriber2");
// Nastavenie odberov YouTube kanala
youtubeKanal.odoberat(odoberatel1);
youtubeKanal.odoberat(odoberatel2);
// Pridanie noveho videa, vsetci odoberatelia dostanu upozornenie
youtubeKanal.nahratNoveVideo("Navrhove vzory v Jave");
// Odoberatel 1 odhlasi odber
youtubeKanal.zrusitOdber(odoberatel1);
// Pridanie dalsieho videa, notifikaciu dostatne len Odoberatel 2
youtubeKanal.nahratNoveVideo("Java SDK 21");
}
}
V triede Main simulujeme prevádzku jedného YouTube kanála, kam sa používatelia (odberatelia) môžu prihlásiť a pri pridaní nového videa sú všetci odberatelia notifikovaní. Rovnako vidieť, že po odhlásení z odberu, používateľ prestane dostávať upozornenie na nový obsah.
Výstup z tohto príkladu je:
Zhrnutie
Vzor Observer sa používa v systémoch, ktoré spracovávajú udalosti, napr. v GUI komponentoch (kliknutie myši na tlačidlo), ale sú užitočné všade tam, kde chceme flexibilne reagovať na zmenu na pozorovanom objekte.
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 Observer tu.
Ak hľadáš prácu a si Java programátor, pozri si naše benefity pre zamestnancov a reaguj na najnovšie ponuky práce.