A megfigyelő minta Java-ban

1. Áttekintés

Ebben a cikkben leírjuk a Observer mintát, és megnézünk néhány Java megvalósítási alternatívát.

2. Mi a megfigyelő minta?

A megfigyelő egy viselkedésbeli mintázat. Megadja az objektumok közötti kommunikációt: megfigyelhető és megfigyelők. An megfigyelhető olyan objektum, amely értesít megfigyelők állapotának változásáról.

Például egy hírügynökség értesítheti a csatornákat, ha híreket kap. A hírek beérkezése megváltoztatja a hírügynökség állapotát, és ez a csatornákat értesíti.

Lássuk, hogyan tudjuk megvalósítani magunk.

Először határozzuk meg a Hírügynökség osztály:

public class NewsAgency {private String hírek; private list csatornák = new ArrayList (); public void addObserver (Csatorna csatorna) {this.csatornák.add (csatorna); } public void removeObserver (Channel channel) {this.csatornák.eltávolítás (channel); } public void setNews (String hírek) {this.news = hírek; for (Csatorna csatorna: ez.csatornák) {channel.update (this.news); }}}

Hírügynökség megfigyelhető, és mikor hírek frissül, a állapot Hírügynökség változtatások. Amikor a változás bekövetkezik, Hírügynökség értesíti a megfigyelőket erről a tényről, felhívva őket frissítés () módszer.

Ahhoz, hogy ezt megtehesse, a megfigyelhető objektumnak meg kell őriznie a megfigyelőkre való hivatkozásokat, és esetünkben ez a csatornák változó.

Most nézzük meg, hogy a megfigyelő, a Csatorna osztály, kinézhet. Meg kell lennie a frissítés () metódus, amelyre akkor hivatkozunk, amikor Hírügynökség változtatások:

public class NewsChannel megvalósítja a Channel {private String híreket; @Orride public void update (Object news) {this.setNews ((String) news); }}

A Csatorna az interfésznek csak egy módszere van:

nyilvános felület Csatorna {public void update (o objektum); }

Most, ha hozzáadjuk a NewsChannel a megfigyelők listájára, és megváltoztatja a Hírügynökség, a NewsChannel Frissítve lesz:

NewsAgency megfigyelhető = new NewsAgency (); NewsChannel megfigyelő = new NewsChannel (); megfigyelhető.addObserver (megfigyelő); megfigyelhető.setNews ("hír"); assertEquals (observer.getNews (), "hírek");

Van egy előre definiált Megfigyelő felület a Java magkönyvtárakban, ami még egyszerűbbé teszi a megfigyelő minta megvalósítását. Nézzük meg.

3. Végrehajtás Megfigyelő

A java.util.Figyelő interfész határozza meg a frissítés () módszerrel, tehát nem kell magunknak meghatároznunk, mint az előző szakaszban.

Lássuk, hogyan tudjuk felhasználni a megvalósításban:

nyilvános osztályú ONewsChannel megvalósítja Observer {private String news; @Orride public void update (Observable o, Object news) {this.setNews ((String) news); }} 

Itt a második érv származik Megfigyelhető amint alább láthatjuk.

A megfigyelhető meghatározásához, bővítenünk kell a Java-kat Megfigyelhető osztály:

az ONewsAgency nyilvános osztály kiterjeszti Megfigyelhető {private String hírek; public void setNews (String hírek) {this.news = hírek; setChanged (); értesítsenMegfigyelők (hírek); }}

Ne feledje, hogy nem kell felhívnunk a megfigyelőt frissítés () módszerrel. Csak hívunk setChanged () és értesítsen megfigyelőket (), és a Megfigyelhető osztály a többit megteszi helyettünk.

Ezenkívül tartalmazza a megfigyelők listáját, és bemutatja a lista fenntartásának módszereit - addObserver () és deleteObserver ().

Az eredmény teszteléséhez csak fel kell tennünk a megfigyelőt ehhez a listához, és be kell állítanunk a híreket:

Megfigyelhető ONewsAgency = új ONewsAgency (); ONewsChannel megfigyelő = új ONewsChannel (); megfigyelhető.addObserver (megfigyelő); megfigyelhető.setNews ("hír"); assertEquals (observer.getNews (), "hírek");

Megfigyelő A felület nem tökéletes, és a Java 9 óta elavult. Ennek egyik hátránya Megfigyelhető nem interfész, hanem osztály, ezért az alosztályokat nem lehet megfigyelhetőként használni.

Ezenkívül egy fejlesztő felülírhatja a MegfigyelhetőSzinkronizált módszerei és megzavarják azok menetbiztonságát.

Nézzük meg a ProperyChangeListener felület, amely használata helyett ajánlott Megfigyelő.

4. Végrehajtás PropertyChangeListener

Ebben a megvalósításban egy megfigyelhetőnek meg kell őriznie a hivatkozást PropertyChangeSupport példa. Segít elküldeni az értesítéseket a megfigyelőknek, ha az osztály tulajdonságai megváltoznak.

Határozzuk meg a megfigyelhetőt:

nyilvános osztály PCLNewsAgency {private String news; private PropertyChangeSupport támogatás; 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 (karakterlánc értéke) {support.firePropertyChange ("hír", ez.új, érték); this.news = érték; }}

Ennek felhasználásával támogatás, felvehetünk és eltávolíthatunk megfigyelőket, és értesíthetjük őket, ha a megfigyelhető állapot megváltozik:

support.firePropertyChange ("hír", ez.új, érték);

Itt az első argumentum a megfigyelt tulajdonság neve. A második és a harmadik érv ennek megfelelően régi és új értéke.

A megfigyelőknek végre kell hajtaniuk PropertyChangeListener:

nyilvános osztályú PCLNewsChannel valósítja meg a PropertyChangeListener {private String news; public void propertyChange (PropertyChangeEvent evt) {this.setNews ((String) evt.getNewValue ()); }}

Miatt a PropertyChangeSupport osztály, amely elvégzi a vezetékeket helyettünk, vissza tudjuk állítani az új tulajdonság értékét az eseményből.

Teszteljük a megvalósítást, hogy megbizonyosodjon arról, hogy az is működik:

PCLNewsAgency megfigyelhető = new PCLNewsAgency (); PCLNewsChannel megfigyelő = new PCLNewsChannel (); megfigyelhető.addPropertyChangeListener (megfigyelő); megfigyelhető.setNews ("hír"); assertEquals (observer.getNews (), "hírek");

5. Következtetés

Ebben a cikkben két módszert vizsgáltunk a Megfigyelő tervezési minta Java-ban, a PropertyChangeListener megközelítést részesítik előnyben.

A cikk forráskódja elérhető a GitHubon.