Observatørmønsteret i Java

1. Oversikt

I denne artikkelen skal vi beskrive Observer-mønsteret og se på noen få Java-implementeringsalternativer.

2. Hva er observatørmønsteret?

Observer er et atferdsmønster. Den spesifiserer kommunikasjon mellom objekter: observerbar og observatører. An observerbar er et objekt som varsler observatører om endringene i tilstanden.

Et nyhetsbyrå kan for eksempel varsle kanaler når det mottar nyheter. Motta nyheter er det som endrer tilstanden til nyhetsbyrået, og det får kanalene til å bli varslet.

La oss se hvordan vi kan implementere det selv.

La oss først definere Nyhetsbyrå klasse:

offentlig klasse NewsAgency {private String nyheter; private List-kanaler = ny ArrayList (); public void addObserver (Channel channel) {this.channels.add (channel); } public void removeObserver (Channel channel) {this.channels.remove (channel); } public void setNews (String news) {this.news = nyheter; for (Channel channel: this.channels) {channel.update (this.news); }}}

Nyhetsbyrå er en observerbar, og når nyheter blir oppdatert, tilstanden til Nyhetsbyrå Endringer. Når endringen skjer, Nyhetsbyrå varsler observatørene om dette ved å ringe deres Oppdater() metode.

For å kunne gjøre det, må det observerbare objektet beholde referanser til observatørene, og i vårt tilfelle er det kanaler variabel.

La oss nå se hvordan observatøren, de Kanal klasse, kan se ut. Det skal ha Oppdater() metoden som påberopes når staten Nyhetsbyrå Endringer:

offentlig klasse NewsChannel implementerer Channel {private String news; @Override public void update (Object news) {this.setNews ((String) news); }}

De Kanal grensesnittet har bare en metode:

offentlig grensesnitt Channel {public void update (Object o); }

Nå, hvis vi legger til en forekomst av NewsChannel til listen over observatører, og endre tilstanden til Nyhetsbyrå, forekomsten av NewsChannel vil bli oppdatert:

NewsAgency observerbar = ny NewsAgency (); NewsChannel observatør = ny NewsChannel (); observerbar.addObserver (observatør); observerbar.setNews ("nyheter"); assertEquals (observer.getNews (), "nyheter");

Det er en forhåndsdefinert Observatør grensesnitt i Java-kjernebiblioteker, noe som gjør implementeringen av observatørmønsteret enda enklere. La oss se på det.

3. Implementering med Observatør

De java.util.Observer grensesnitt definerer Oppdater() metode, så det er ikke nødvendig å definere det selv som vi gjorde i forrige avsnitt.

La oss se hvordan vi kan bruke det i implementeringen:

offentlig klasse ONewsChannel implementerer Observer {private String nyheter; @Override offentlig ugyldig oppdatering (Observable o, Object news) {this.setNews ((String) news); }} 

Her kommer det andre argumentet fra Observerbar som vi får se nedenfor.

Å definere det observerbare, vi må utvide Java-er Observerbar klasse:

offentlig klasse ONewsAgency utvider Observable {private String news; public void setNews (String news) {this.news = nyheter; setChanged (); varsleObservere (nyheter); }}

Merk at vi ikke trenger å ringe observatørens Oppdater() metode direkte. Vi bare ringer setChanged () og notifyObservers (), og Observerbar klassen gjør resten for oss.

Den inneholder også en liste over observatører og avslører metoder for å opprettholde den listen - addObserver () og deleteObserver ().

For å teste resultatet, trenger vi bare å legge observatøren til denne listen og sette nyheter:

ONewsAgency observerbar = ny ONewsAgency (); ONewsChannel observatør = ny ONewsChannel (); observerbar.addObserver (observatør); observerbar.setNews ("nyheter"); assertEquals (observer.getNews (), "nyheter");

Observatør grensesnittet er ikke perfekt og er utfaset siden Java 9. En av ulempene er det Observerbar er ikke et grensesnitt, men en klasse, det er derfor underklasser ikke kan brukes som observerbare.

En utvikler kan også overstyre noe av ObserverbarSine synkroniserte metoder og forstyrrer trådsikkerheten.

La oss se på ProperyChangeListener grensesnitt, som anbefales i stedet for å bruke Observatør.

4. Implementering med PropertyChangeListener

I denne implementeringen må en observerbar beholde en referanse til PropertyChangeSupport forekomst. Det hjelper å sende varslene til observatører når en eiendom i klassen endres.

La oss definere det observerbare:

offentlig klasse PCLNewsAgency {private String nyheter; privat PropertyChangeSupport-støtte; offentlig PCLNewsAgency () {support = new PropertyChangeSupport (dette); } offentlig tomrom addPropertyChangeListener (PropertyChangeListener pcl) {support.addPropertyChangeListener (pcl); } public void removePropertyChangeListener (PropertyChangeListener pcl) {support.removePropertyChangeListener (pcl); } public void setNews (String value) {support.firePropertyChange ("news", this.news, value); this.news = verdi; }}

Bruker dette Brukerstøtte, kan vi legge til og fjerne observatører, og varsle dem når tilstanden til det observerbare endres:

support.firePropertyChange ("nyheter", dette. nyheter, verdi);

Her er det første argumentet navnet på den observerte eiendommen. Det andre og det tredje argumentet er dets gamle og nye verdi tilsvarende.

Observatører bør implementere PropertyChangeListener:

offentlig klasse PCLNewsChannel implementerer PropertyChangeListener {private String nyheter; public void propertyChange (PropertyChangeEvent evt) {this.setNews ((String) evt.getNewValue ()); }}

På grunn av PropertyChangeSupport klasse som gjør ledningene for oss, kan vi gjenopprette den nye eiendomsverdien fra hendelsen.

La oss teste implementeringen for å sikre at den også fungerer:

PCLNewsAgency observerbar = ny PCLNewsAgency (); PCLNewsChannel observatør = ny PCLNewsChannel (); observerbar.addPropertyChangeListener (observatør); observerbar.setNews ("nyheter"); assertEquals (observer.getNews (), "nyheter");

5. Konklusjon

I denne artikkelen har vi undersøkt to måter å implementere Observatør designmønster i Java, med PropertyChangeListener tilnærming blir foretrukket.

Kildekoden for artikkelen er tilgjengelig på GitHub.


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