Java設計模式11:觀察者模式
一、什麼是觀察者模式
在閻巨集博士的《JAVA與模式》一書中開頭是這樣描述觀察者(Observer)模式的:
觀察者模式是物件的行為模式,又叫釋出-訂閱(Publish/Subscribe)模式、模型-檢視(Model/View)模式、源-監聽器(Source/Listener)模式或從屬者(Dependents)模式。
觀察者模式定義了一種一對多的依賴關係,讓多個觀察者物件同時監聽某一個主題物件。這個主題物件在狀態上發生變化時,會通知所有觀察者物件,使它們能夠自動更新自己。
二、觀察者模式所涉及的角色
抽象被觀察者角色:也就是一個抽象主題,它把所有對觀察者物件的引用儲存在一個集合中,每個主題都可以有任意數量的觀察者。抽象主題提供一個介面,可以增加和刪除觀察者角色。一般用一個抽象類和介面來實現。
抽象觀察者角色:為所有的具體觀察者定義一個介面,在得到主題通知時更新自己。
具體被觀察者角色:也就是一個具體的主題,在集體主題的內部狀態改變時,所有登記過的觀察者發出通知。
具體觀察者角色:實現抽象觀察者角色所需要的更新介面,一邊使本身的狀態與製圖的狀態相協調。
三、程式碼示例:
在上程式碼之前,我們先假設下這樣的使用場景:有一個通知服務(比如微信公眾號),向用戶推送訊息,使用者關注公眾號就可以收到推送訊息,取消關注就收不到推送訊息。
先建立抽象觀察者介面和抽象被觀察者介面
/**
* <pre>
* @author : orange
* @e-mail : [email protected]
* @time : 2018/10/18 10:40
* @desc : 抽象觀察者介面
* @version: 1.0
* </pre>
*/
public interface Observer {
public void update(String message);
}
/** * <pre> * @author : orange * @e-mail : [email protected] * @time : 2018/10/18 10:39 * @desc : 抽象被觀察者介面 * @version: 1.0 * </pre> */ public interface Observerable { public void addObserver(Observer observer); public void removeObserver(Observer observer); public void notifyObserver(); }
被觀察者介面實現類:
/**
* <pre>
* @author : orange
* @e-mail : [email protected]
* @time : 2018/10/18 10:43
* @desc : 具體的被觀察者實現
* @version: 1.0
* </pre>
*/
public class ObserverableImpl implements Observerable{
private List<Observer> list = new ArrayList<>();
private String message;
@Override
public void addObserver(Observer observer) {
list.add(observer);
}
@Override
public void removeObserver(Observer observer) {
list.remove(observer);
}
@Override
public void notifyObserver() {
for (int i = 0; i < list.size(); i++) {
Observer observer = list.get(i);
observer.update(message);
}
}
public void pushMessage(String message){
this.message = message;
//通知所有觀察者,推送訊息
notifyObserver();
}
}
具體的觀察者:
/**
* <pre>
* @author : orange
* @e-mail : [email protected]
* @time : 2018/10/18 11:00
* @desc :
* @version: 1.0
* </pre>
*/
public class User implements Observer {
private String mrssage;
private String name;
public User(String name) {
this.name = name;
}
@Override
public void update(String message) {
this.mrssage = message;
System.out.println(name + "收到推送訊息:" + message);
}
}
最後客戶端測試:
/**
* <pre>
* @author : orange
* @e-mail : [email protected]
* @time : 2018/10/18 11:03
* @desc : 客戶端測試
* @version: 1.0
* </pre>
*/
public class Client {
public static void main(String[] args){
ObserverableImpl observerable = new ObserverableImpl();
Observer observer1 = new User("張飛");
Observer observer2 = new User("關羽");
Observer observer3 = new User("劉備");
observerable.addObserver(observer1);
observerable.addObserver(observer2);
observerable.addObserver(observer3);
observerable.pushMessage("通知來了");
}
}
四、總結:
觀察者模式的好處:
觀察者模式提供了一種物件設計,讓主題和觀察者之間耦合度降得很低,為什麼呢?關於觀察者的一切,主題只知道觀察者實現了Observer介面,並不需要觀察者具體的類是誰,做了什麼或者其他細節.
這樣的話,由於鬆耦合,改變主題或者觀察者其中一方,並不會影響另一方,只要他們之間的介面仍被遵守,就可以自由地改變它.
降低物件之間的耦合度,也是面設物件設計的一個很重要的原則.