Uzorak promatrača u Javi

1. Pregled

U ovom ćemo članku opisati obrazac Observer i pogledati nekoliko alternativa za implementaciju Jave.

2. Što je obrazac promatrača?

Promatrač je obrazac dizajna ponašanja. Određuje komunikaciju između objekata: uočljiv i promatrači. An uočljiv je objekt koji obavještava promatrači o promjenama u njenom stanju.

Na primjer, novinska agencija može obavijestiti kanale kad primi vijesti. Primanje vijesti je ono što mijenja stanje novinske agencije i dovodi do obavještavanja kanala.

Pogledajmo kako to možemo sami primijeniti.

Prvo, definirajmo Novinska agencija razred:

public class NewsAgency {private String news; privatni kanali s popisa = novi ArrayList (); javna void addObserver (kanal kanala) {this.channels.add (kanal); } javna praznina removeObserver (kanal kanala) {this.channels.remove (channel); } public void setNews (String news) {this.news = vijesti; for (Channel channel: this.channels) {channel.update (this.news); }}}

Novinska agencija je vidljivo i kada vijesti ažurira, stanje Novinska agencija promjene. Kada se promjena dogodi, Novinska agencija obavještava promatrače o ovoj činjenici pozivanjem svojih ažuriranje() metoda.

Da bi to mogao učiniti, promatrani objekt mora zadržati reference na promatrače, a u našem slučaju to je kanali varijabilna.

Pogledajmo sada kako promatrač, the Kanal razreda, može izgledati. Trebalo bi imati ažuriranje() metoda koja se poziva kada se stanje Novinska agencija promjene:

NewsChannel javne klase implementira Channel {private String news; @Preuzmi javno prazno ažuriranje (vijesti o objektu) {this.setNews ((string) vijesti); }}

The Kanal sučelje ima samo jednu metodu:

javno sučelje Channel {javno prazno ažuriranje (objekt o); }

Sada, ako dodamo primjerak NewsChannel na popis promatrača, i promijeniti stanje u Novinska agencija, instanca NewsChannel bit će ažurirano:

NewsAgency observable = novi NewsAgency (); NewsChannel promatrač = novi NewsChannel (); observable.addObserver (promatrač); observable.setNews ("vijesti"); assertEquals (observer.getNews (), "news");

Postoji unaprijed definirano Posmatrač sučelje u osnovnim knjižnicama Java, što čini provedbu uzorka promatrača još jednostavnijom. Pogledajmo to.

3. Provedba sa Posmatrač

The java.util.Observer sučelje definira ažuriranje() metodu, tako da nema potrebe da je sami definiramo kao što smo to učinili u prethodnom odjeljku.

Pogledajmo kako ga možemo koristiti u našoj implementaciji:

javna klasa ONewsChannel implementira Observer {private String news; @Preuzmi javno void ažuriranje (Observable o, Object news) {this.setNews ((String) vijesti); }} 

Ovdje dolazi drugi argument Uočljiv kao što ćemo vidjeti u nastavku.

Da definiramo opažljivo, moramo proširiti Java Uočljiv razred:

javna klasa ONewsAgency proširuje Observable {private String news; public void setNews (String news) {this.news = vijesti; setChanged (); notifyObservers (vijesti); }}

Imajte na umu da ne trebamo zvati promatrača ažuriranje() metoda izravno. Samo zovemo setChanged () i notifyObservers (), i Uočljiv razred čini ostalo za nas.

Također sadrži popis promatrača i izlaže metode za održavanje tog popisa - addObserver () i deleteObserver ().

Da bismo testirali rezultat, samo moramo dodati promatrača na ovaj popis i postaviti vijesti:

ONewsAgency uočljivo = novo ONewsAgency (); ONewsChannel promatrač = novi ONewsChannel (); observable.addObserver (promatrač); observable.setNews ("vijesti"); assertEquals (observer.getNews (), "news");

Posmatrač sučelje nije savršeno i zastarjelo je od Jave 9. Jedna od njegovih nedostataka je ta Uočljiv nije sučelje već klasa, zato se potklase ne mogu koristiti kao vidljive.

Također, programer bi mogao nadjačati neke od Uočljiv'S sinkroniziranim metodama i narušavaju njihovu sigurnost niti.

Pogledajmo ProperyChangeListener sučelje, koje se preporučuje umjesto upotrebe Posmatrač.

4. Provedba sa PropertyChangeListener

U ovoj provedbi, promatrač mora zadržati referencu na PropertyChangeSupport primjer. Pomaže slanje obavijesti promatračima kada se promijeni svojstvo klase.

Definirajmo uočljivo:

javna klasa PCLNewsAgency {private String vijesti; privatna podrška za PropertyChangeSupport; public PCLNewsAgency () {support = new PropertyChangeSupport (this); } javna void addPropertyChangeListener (PropertyChangeListener pcl) {support.addPropertyChangeListener (pcl); } javna praznina removePropertyChangeListener (PropertyChangeListener pcl) {support.removePropertyChangeListener (pcl); } javna void setNews (vrijednost niza) {support.firePropertyChange ("vijesti", this.news, vrijednost); this.news = vrijednost; }}

Koristeći ovo podrška, možemo dodati i ukloniti promatrače i obavijestiti ih kada se stanje vidljivog promijeni:

support.firePropertyChange ("vijesti", this.news, vrijednost);

Ovdje je prvi argument naziv promatranog svojstva. Drugi i treći argument su njegova stara i nova vrijednost u skladu s tim.

Promatrači bi trebali provoditi PropertyChangeListener:

javna klasa PCLNewsChannel implementira PropertyChangeListener {private String vijesti; public void propertyChange (PropertyChangeEvent evt) {this.setNews ((String) evt.getNewValue ()); }}

Zbog PropertyChangeSupport klase koja za nas vrši ožičenje, možemo vratiti novu vrijednost svojstva iz događaja.

Isprobajmo implementaciju kako bismo bili sigurni da i ona funkcionira:

PCLNewsAgency observable = novi PCLNewsAgency (); PCLNewsChannel promatrač = novi PCLNewsChannel (); observable.addPropertyChangeListener (promatrač); observable.setNews ("vijesti"); assertEquals (observer.getNews (), "news");

5. Zaključak

U ovom smo članku ispitali dva načina za implementaciju Posmatrač dizajn uzorka na Javi, sa PropertyChangeListener pristup se preferira.

Izvorni kôd članka dostupan je na GitHubu.