初探Java設計模式------觀察者模式
阿新 • • 發佈:2019-01-27
前言
最近剛開始學習RxJava,眾所周知,Rxjava就是擴充套件的觀察者模式,所以想學習Rxjava,先入手瞭解一下觀察者模式是很有必要的。那麼今天就先稍微瞭解一下什麼是觀察者模式。
定義
觀察者(Observer)模式:是物件的行為模式,也叫做釋出-訂閱(Publish/Subscribe)模式、模型-檢視(Module/View)模式、源-監聽(Source/Listener)模式或者從(Dependents)模式。
觀察者模式定義了一對多的依賴關係,即讓多個觀察者物件同時監聽同一個主題物件,當這個主題物件的狀態發生改變時,要通知所有的觀察者物件,使他們能夠更新自己。
!
眾大神部落格裡面最多的例子就是天氣預報和小偷警察的例子。拿小偷和警察的例子來說,小偷就是被觀察者,而警察就是觀察者。多個警察在關注小偷的行為,當小偷想偷東西時,即主題物件狀態發生改變時,這個時候很多警察就會上去抓住他,也就是觀察者更新了自己的行為。
UML類圖
我們來解釋一下UML圖中的含義:
Subject
主題,即被觀察者介面,它是一個抽象的介面,包含三個方發,attach()即增加訂閱者,detach()刪除訂閱者,notifyObserver()通知訂閱者;Observer
觀察者介面,它是一個抽象的介面,其中含有一個update()方發,用來在被觀察者狀態改變的時候進行更新自己。ConcreteSubject
被觀察者物件,實現了被觀察者介面,同時有一個List集合,用以儲存註冊的觀察者,等需要通知觀察者時,遍歷該集合即可。注意,該集合的泛型引數應該是Observer,介面型別,而不應該是具體的Observer實現類,這樣做的原因是一個被觀察者可能會有多個不同實現類的觀察者(但都實現了Observer介面),如果限定了某一個具體的型別,那麼會導致以後要加入新型別的時候而不得不修改當前類,耦合度過高,這是一個非常不好的行為。ConcreteObserver
實現步驟
1.建立介面和抽象類
public interface Observer {
public String getmName();
void update(String weather);
}
public abstract class Subject {
//儲存觀察者的集合
public List<Observer> observers=new ArrayList<Observer>();
/**
* 新增觀察者
* @param observer
*/
public void attach(Observer observer){
observers.add(observer);
System.out.println(observer.getmName()+"訂閱天氣預報");
}
/**
* 移除觀察者
*/
public void detach(Observer observer){
observers.remove(observer);
System.out.println(observer.getmName()+"取消訂閱天氣預報");
}
/**
* 通知所有的觀察者改變狀態
*/
public void notifyObservers(String weather){
for(Observer observer:observers){
observer.update(weather);
}
}}
2.實現觀察者介面
public class ObserserPeople implements Observer {
private String mName;
public ObserserPeople(String name){
this.mName=name;
}
public void update(String weather) {
System.out.println(mName+"收到天氣預報訊息"+weather);
}
public String getmName() {
return mName;
}}
3.繼承被觀察者抽象類
public class WeatherSubject extends Subject {
public void change(String weather){
notifyObservers(weather);
}}
這樣我們就寫完了,下面我們編寫一個測試類:
public class Test {
public static void main(String[] args) {
Observer observer=new ObserserPeople("校長");
Observer observer2=new ObserserPeople("主任");
Observer observer3=new ObserserPeople("老師");
WeatherSubject subject=new WeatherSubject();
subject.attach(observer);
subject.attach(observer2);
subject.attach(observer3);
subject.change("下個周即將下雪!!!");
subject.detach(observer3);
subject.change("下週不下雪了!");
}}
輸出結果如下:
校長訂閱天氣預報
主任訂閱天氣預報
老師訂閱天氣預報
校長收到天氣預報訊息下個周即將下雪!!!
主任收到天氣預報訊息下個周即將下雪!!!
老師收到天氣預報訊息下個周即將下雪!!!
老師取消訂閱天氣預報
校長收到天氣預報訊息下週不下雪了!
主任收到天氣預報訊息下週不下雪了!
通過上面例子,可以看出,當觀察者訂閱了被觀察者時,被觀察者改變立馬會通知觀察者,觀察者就會執行update()方法。當然,我在這裡沒有做實現。具體可以更具業務邏輯來進行實現。