Vzor pozorovateľa v Jave

1. Prehľad

V tomto článku popíšeme vzor Observer a pozrieme sa na niekoľko alternatív implementácie Java.

2. Čo je vzor pozorovateľa?

Pozorovateľ je návrhový vzor správania. Určuje komunikáciu medzi objektmi: pozorovateľný a pozorovatelia. An pozorovateľný je predmet, ktorý oznamuje pozorovatelia o zmenách jeho stavu.

Spravodajská agentúra môže napríklad informovať kanály, keď prijíma správy. Príjem správ mení stav spravodajskej agentúry a spôsobuje informovanie kanálov.

Pozrime sa, ako to môžeme sami realizovať.

Najskôr definujme Tlačová agentúra trieda:

public class NewsAgency {private String news; kanály súkromného zoznamu = new ArrayList (); public void addObserver (kanál kanála) {this.channels.add (kanál); } public void removeObserver (kanál kanála) {this.channels.remove (kanál); } public void setNews (reťazcové správy) {this.news = novinky; pre (Kanál kanála: this.channels) {channel.update (this.news); }}}

Tlačová agentúra je pozorovateľný a kedy novinky sa aktualizuje, stav Tlačová agentúra zmeny. Keď dôjde k zmene, Tlačová agentúra upozorňuje pozorovateľov na túto skutočnosť volaním svojho aktualizácia () metóda.

Aby to bolo možné dosiahnuť, musí si pozorovateľný objekt uchovávať odkazy na pozorovateľov, a v našom prípade je to kanály premenná.

Poďme sa teraz pozrieť, ako na to pozorovateľ, the Kanál triedy, môže vyzerať. Mal by mať aktualizácia () metóda, ktorá sa vyvolá pri stave Tlačová agentúra zmeny:

public class NewsChannel implementuje Channel {private String news; @Override public void update (Object news) {this.setNews ((String) novinky); }}

The Kanál rozhranie má iba jednu metódu:

verejné rozhranie Kanál {public void update (Objekt o); }

Teraz, keď pridáme inštanciu NewsChannel do zoznamu pozorovateľov, a zmeniť stav Tlačová agentúra, inštancia NewsChannel bude aktualizované:

NewsAgency pozorovateľná = nová NewsAgency (); Pozorovateľ NewsChannel = nový NewsChannel (); pozorovateľný.addObserver (pozorovateľ); observable.setNews ("novinky"); assertEquals (observer.getNews (), "novinky");

Je tu preddefinované Pozorovateľ rozhranie v základných knižniciach Java, čo ešte viac zjednodušuje implementáciu vzoru pozorovateľa. Pozrime sa na to.

3. Implementácia s Pozorovateľ

The java.util.Observer rozhranie definuje aktualizácia () metóda, takže nie je potrebné ju definovať sami, ako sme to robili v predchádzajúcej časti.

Pozrime sa, ako to môžeme použiť pri našej implementácii:

verejná trieda ONewsChannel implementuje Observer {private String news; @Override public void update (Pozorovateľný o, Objektové správy) {this.setNews ((String) novinky); }} 

Tu vychádza druhý argument Pozorovateľné ako uvidíme ďalej.

Definovať pozorovateľné, musíme rozšíriť Javu Pozorovateľné trieda:

public class ONewsAgency rozširuje Observable {private String news; public void setNews (String news) {this.news = novinky; setChanged (); notifyObservers (novinky); }}

Upozorňujeme, že nemusíme volať pozorovateľovi aktualizácia () metóda priamo. Len zavoláme setChanged () a notifyObservers ()a Pozorovateľné trieda robí zvyšok za nás.

Obsahuje tiež zoznam pozorovateľov a zverejňuje metódy na jeho udržanie - addObserver () a deleteObserver ().

Ak chcete otestovať výsledok, stačí do tohto zoznamu pridať pozorovateľa a nastaviť novinky:

ONewsAgency pozorovateľný = nový ONewsAgency (); ONewsChannel observer = nový ONewsChannel (); pozorovateľný.addObserver (pozorovateľ); observable.setNews ("novinky"); assertEquals (observer.getNews (), "novinky");

Pozorovateľ rozhranie nie je dokonalé a od verzie Java 9 je zastarané. Jednou z jeho nevýhod je to Pozorovateľné nie je rozhranie, ale trieda, preto podtriedy nemožno použiť ako pozorovateľné.

Vývojár môže tiež prepísať niektoré z týchto PozorovateľnéSynchronizované metódy a narúšajú ich bezpečnosť vlákien.

Pozrime sa na ProperyChangeListener rozhranie, ktoré sa namiesto použitia odporúča Pozorovateľ.

4. Implementácia s PropertyChangeListener

Pri tejto implementácii si pozorovateľ musí ponechať odkaz na PropertyChangeSupport inštancia. Pomáha posielať upozornenia pozorovateľom pri zmene vlastnosti triedy.

Definujme pozorovateľné:

public class PCLNewsAgency {private String news; podpora súkromnej PropertyChangeSupport; public PCLNewsAgency () {support = new PropertyChangeSupport (this); } public void addPropertyChangeListener (PropertyChangeListener pcl) {support.addPropertyChangeListener (pcl); } public void removePropertyChangeListener (PropertyChangeListener pcl) {support.removePropertyChangeListener (pcl); } public void setNews (hodnota reťazca) {support.firePropertyChange ("novinky", this.news, hodnota); this.news = hodnota; }}

Pomocou tohto podpora, môžeme pridávať a odoberať pozorovateľov a informovať ich, keď sa stav pozorovateľných zmien zmení:

support.firePropertyChange ("novinky", this.news, hodnota);

Tu je prvým argumentom názov pozorovanej vlastnosti. Druhý a tretí argument zodpovedajú svojej starej a novej hodnote.

Pozorovatelia by to mali implementovať PropertyChangeListener:

verejná trieda PCLNewsChannel implementuje PropertyChangeListener {súkromné ​​správy reťazcov; public void propertyChange (PropertyChangeEvent evt) {this.setNews ((String) evt.getNewValue ()); }}

V dôsledku PropertyChangeSupport triedy, ktorá za nás robí elektroinštaláciu, môžeme z udalosti obnoviť novú hodnotu vlastnosti.

Vyskúšajme implementáciu, aby sme sa uistili, že tiež funguje:

PCLNewsAgency pozorovateľné = nové PCLNewsAgency (); Pozorovateľ PCLNewsChannel = nový PCLNewsChannel (); observable.addPropertyChangeListener (pozorovateľ); observable.setNews ("novinky"); assertEquals (observer.getNews (), "novinky");

5. Záver

V tomto článku sme preskúmali dva spôsoby implementácie Pozorovateľ návrhový vzor v Jave, s PropertyChangeListener uprednostňovaný prístup.

Zdrojový kód článku je k dispozícii na GitHub.


$config[zx-auto] not found$config[zx-overlay] not found