手寫一個觀察者模式(JAVA Demo)
首先理解一下觀察者模式的定義:
定義物件間一種一對多的依賴關係,使得每當一個物件改變狀態,則所有依賴於它的物件都會得到通知並被自動更新。
直譯:
建立一個一(Subject)對多(Observer)的關係,能夠使得當"一"變化的時候,依賴這個"一"的多也能夠同步改變。
觀察者模式所涉及的角色有:
-
抽象主題(Subject)角色:即被觀察者(Observable)的角色,主題的抽象類,抽象主題角色把所有觀察者物件的引用儲存在一個集合裡,每個主題都可以有任意數量的觀察者,抽象主題提供一個介面,可以增加和刪除觀察者物件。
-
具體主題(ConcreteSubject)角色:即具體被觀察者(ConcreteObservable),此角色將有關狀態存入具體觀察者物件,在具體主題的內部狀態發生改變時,給所有註冊過的觀察者發出通知。
-
抽象觀察者(Observer)角色:此角色是觀察者的介面類,它定義了一個更新介面,在得到主題的通知時更新自己。
-
具體觀察者(ConcreteObserver)角色:該主題實現抽象觀察者角色所定義的更新介面,以便在主題的狀態發生變化時更新自身的狀態。
以上就是觀察者模式的基本內容,現在要開始寫一個觀察者模式的程式碼前,請先檢查下我們的“武器”:
在JAVA語言的API中,提供了一個Observable抽象類以及一個Observer介面,構成JAVA語言對觀察者模式的支援。
- Observable抽象類 抽象主題角色,具體主題類必須繼承該抽象類,同時抽象主題提供一個介面
- Observer介面類,抽象觀察者角色,具體觀察者必須實現該介面,同時它定義了一個更新介面,具體觀察者必須實現該更新方法。
觀察者模式需要用到的Java類
1 java.util.Observable
-able一般可能...的單詞字尾,Observable就是可以被觀察的,程式中的被觀察者類,需要繼承這個類。
2 java.util.Observer
這個是觀察者,是介面。程式中的觀察者類,需要實現這個介面中的update()方法。
下面開始講解觀察者模式的JAVA Demo:
(1)觀察者物件User 一個介面類,必須實現update方法(獲取更新訊息)
/**
* 微信使用者是具體觀察物件
* @author xiazheng
*
*/
package com.Observer;
import java.util.Observable;
import java.util.Observer;
public class User implements Observer{
private String name;
public User(String name){
this.name = name;
}
@Override
public void update(Observable o, Object arg) {
// TODO Auto-generated method stub
System.out.println("微信使用者:"+name+",您的微信公眾號更新這些內容:"+arg);
}
}
(2)被觀察者物件OfficialAccount ,需要重寫一個訊息通知方法(publishnewInfo)
/*
* OfficialAccount是具體被觀察的物件:
* 當它更新時,所有監聽該物件的觀察者(微信使用者)都會接收到通知
* */
package com.Observer;
import java.util.Observable;
public class OfficialAccount extends Observable{
/**
*
* @param info 要給觀察者的資訊
*/
public void publishNewInfo(String info){
//標識這個Observable物件已經改變了,更具體來將就是把Observable中屬性changed置為true.
setChanged();
//在通知所有觀察者之前,需要判斷Observable中屬性changed是否為true,如若不為則不會發出通知。
//具體可以看原始碼,蠻好理解的。
notifyObservers(info);
}
}
(3)測試主類
package com.Observer;
public class Test {
public static void main(String[] args) {
//被觀察的角色
OfficialAccount officialAccount = new OfficialAccount();
//觀察者
User userBob = new User("WeChat User-Bob");
User userTom = new User("WeChat User-Tom");
User userMe = new User("WeChat User-Me");
//將觀察者註冊到可觀察物件的觀察者列表中
officialAccount.addObserver(userBob);
officialAccount.addObserver(userTom);
officialAccount.addObserver(userMe);
//釋出訊息
officialAccount.publishNewInfo("...新內容...");
officialAccount.deleteObserver(userMe);
System.out.println("##########################################");
officialAccount.publishNewInfo("...新內容123...");
}
}
測試結果:
新增三個監聽者,三個監聽者都可以收到訊息,刪除掉一個監聽者,只有剩下兩個監聽者可以收到訊息。
User是具體的觀察者,他們訂閱了OfficialAccount這個具體的可觀察物件,當OfficialAccount有更新時,會遍歷所有觀察者。然後給這些觀察者釋出一個更新訊息,之後User中的update方法會呼叫,這樣就達到了一對多的通知功能。