Java設計模式分析之觀察者
大小:0.3 MB 人氣: 2017-09-26 需要積分:1
標簽:JAVA(102450)
觀察者模式的流程跟報紙訂閱方式一致,即:觀察者模式=出版者+訂閱者,只是名稱不一樣,出版者改稱為“主題”(Subject),訂閱者改稱為“觀察者”(Observer)。觀察者定義:
觀察者模式定義了對象之間的一對多依賴,當一個對象改變狀態時,它的所有依賴者都會受到通知并自動更新。
主題接口(Subject):對象使用此接口注冊為觀察者,或者把自己從觀察者中刪除。
具體主題(ConcreteSubject):一個具體主題總是實現主題接口,除了注冊*和撤銷方法以外,具體主題還實現了notifyObserves()方法,此方法用于在狀態改變時更新所有當前觀察者。
觀察者(Observer):為那些在目標發生改變時需獲得通知的對象定義更新的接口
具體觀察者(ConcreteObserver):具體觀察者實現了觀察者Observer接口,并注冊具體主題,以便接收更新。
觀察者模式提供了一種對象設計,讓主題和觀察者之間松耦合,當兩個對象之間松耦合,它們依然可以交互,但是不太清楚彼此的細節,主題只知道觀察者實現了Observer接口,不需要知道觀察者的具體類是誰,做了些什么其他的細節。
觀察者實例:
通過ConcreteObserver注冊兩個觀察者ConcreteObserverA和ConcreteObserverB,一旦被觀察者有更新,兩個觀察者會立刻收到更新通知。具體代碼如下:
聲明Subject主題接口,Subject.java:
publicinterfaceSubject { voidregisterObserver(Observer observer);voidremoveObserver(Observer observer); voidnotifyObservers(); }
聲明ConcreteObserver具體主題,NetConcreteSubject.java:
publicclassNetConcreteSubjectimplementsSubject{privateList《Observer》 observers;privateObserverBean bean; publicNetConcreteSubject() { observers = newArrayList《》(); }@OverridepublicvoidregisterObserver(Observer observer) { observers.add(observer); }@OverridepublicvoidremoveObserver(Observer observer) { intpos = observers.indexOf(observer); if(pos 》 0) { observers.remove(pos); } }@OverridepublicvoidnotifyObservers() { if(bean == null) return; for( inti = 0; i 《 observers.size(); i++) { Observer observer = observers.get(i); observer.update(bean); } }publicvoidsetStatusChanged(ObserverBean bean) { this.bean = bean; notifyObservers(); } }
聲明觀察者接口, Observer.java:
publicinterfaceObserver { voidupdate(Object obj); }
聲明具體觀察者類,ConcreteObserverA.java:
publicclassConcreteObserverAimplementsObserver{@Overridepublicvoidupdate(Object obj) { if(obj instanceofObserverBean) { ObserverBean bean = (ObserverBean) obj; System.out.print( “ConcreteObserverA 網絡類型:”+ bean.netType + “,網絡狀態:”+ bean.netStatus + “\n”); } } }
ConcreteObserverB.java:
publicclassConcreteObserverBimplementsObserver{@Overridepublicvoidupdate(Object obj) { if(obj instanceofObserverBean) { ObserverBean bean = (ObserverBean) obj; System.out.print( “ConcreteObserverB 網絡類型:”+ bean.netType + “,網絡狀態:”+ bean.netStatus + “\n”); } } }
調用過程:
publicstaticvoidmain(String[] args) { //初始化主題(被觀察者)NetConcreteSubject subject =newNetConcreteSubject(); //初始化觀察者AConcreteObserverA observerA =newConcreteObserverA(); //初始化觀察者BConcreteObserverB observerB =newConcreteObserverB(); //注冊觀察者Asubject.registerObserver(observerA); //注冊觀察者Bsubject.registerObserver(observerB); //通知所有觀察者數據有更新ObserverBean bean = newObserverBean( “wifi”, “有網”); subject.setStatusChanged(bean); }
運行結果:
ConcreteObserverA 網絡類型:wifi,網絡狀態:有網 ConcreteObserverB 網絡類型:wifi,網絡狀態:有網Java內置觀察者:
Observable.java:
/** * Java學習交流QQ群:589809992 我們一起學Java! */publicclassObservable{privatebooleanchanged = false; privateVector《Observer》 obs =newVector(); publicObservable() { } publicsynchronizedvoidaddObserver(Observer var1) {if(var1 == null) { thrownewNullPointerException(); } else{ if(! this.obs.contains(var1)) {this.obs.addElement(var1); } } } publicsynchronizedvoiddeleteObserver(Observer var1) {this.obs.removeElement(var1); } publicvoidnotifyObservers() {this.notifyObservers((Object) null); } publicvoidnotifyObservers(Object var1) { Object[] var2; synchronized( this) { if(! this.changed) { return; } var2 = this.obs.toArray();this.clearChanged(); } for( intvar3 = var2.length - 1; var3 》= 0; --var3) { ((Observer)var2[var3]).update( this, var1); } } publicsynchronizedvoiddeleteObservers() {this.obs.removeAllElements(); } protectedsynchronizedvoidsetChanged() { this.changed =true; } protectedsynchronizedvoidclearChanged() { this.changed = false; }publicsynchronizedbooleanhasChanged() { returnthis.changed; }publicsynchronizedintcountObservers() { returnthis.obs.size(); } }
Observer.java:
publicinterfaceObserver { voidupdate(Observable var1, Object var2); }
上面的Observer和Observable類都位于java.util目錄中,是JDK中已經寫好的,那么我們可以直接拿來用了:
主題類NetSubject.java:
publicclassNetSubjectextendsObservable{publicvoidsetNetChanged(ObserverBean bean){ setChanged(); notifyObservers(bean); } }
觀察者SystemObserverA.java:
publicclassSystemObserverAimplementsObserver{@Overridepublicvoidupdate(Observable observable, Object o) { if(o instanceofObserverBean && observable instanceofNetSubject) { ObserverBean bean = (ObserverBean) o; System.out.print( “ConcreteObserverA 網絡類型:”+ bean.netType + “,網絡狀態:”+ bean.netStatus + “\n”); } } }
觀察者SystemObserverB.java:
/** * Java學習交流QQ群:589809992 我們一起學Java! */publicclassSystemObserverBimplementsObserver{@Overridepublicvoidupdate(Observable observable, Object o) { if(o instanceofObserverBean && observable instanceofNetSubject) { ObserverBean bean = (ObserverBean) o; System.out.print( “ConcreteObserverB 網絡類型:”+ bean.netType + “,網絡狀態:”+ bean.netStatus + “\n”); } } }
執行程序:
//初始化主題(被觀察者)NetSubject subject = newNetSubject(); //初始化觀察者ASystemObserverA observerA = newSystemObserverA(); //初始化觀察者BSystemObserverB observerB = newSystemObserverB(); //注冊觀察者Asubject.addObserver(observerA); //注冊觀察者Bsubject.addObserver(observerB); //通知觀察者有更新ObserverBean bean = newObserverBean( “4G流量”, “有網”); subject.setNetChanged(bean);
運行結果:
ConcreteObserverB 網絡類型:4G流量,網絡狀態:有網 ConcreteObserverA 網絡類型:4G流量,網絡狀態:有網
非常好我支持^.^
(0) 0%
不好我反對
(0) 0%