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.