定義
定義對(duì)象間的一種一對(duì)多依賴關(guān)系伪煤,使得每當(dāng)一個(gè)對(duì)象狀態(tài)發(fā)生改變時(shí)辫封,其相關(guān)依賴對(duì)象皆得到通知并被自動(dòng)更新。觀察者模式又叫做發(fā)布-訂閱(Publish-Subscribe)模式素征、模型-視圖(Model-View)模式环凿、源-監(jiān)聽器(Source-Listener)模式或從屬者(Dependents)模式梧兼。
模式結(jié)構(gòu)
觀察者模式包含如下角色:
- Subject: 目標(biāo)
- ConcreteSubject: 具體目標(biāo)
- Observer: 觀察者
- ConcreteObserver: 具體觀察者
UML圖
代碼實(shí)現(xiàn)
Subject.java
/**
* 抽象目標(biāo)者
*/
public abstract class Subject {
// 保存注冊(cè)的觀察者對(duì)象
private List<Observer> mObservers = new ArrayList<>();
//注冊(cè)觀察者對(duì)象
public void attach(Observer observer) {
mObservers.add(observer);
System.out.println("Attached an observer");
}
//注銷觀察者對(duì)象
public void detach(Observer observer) {
mObservers.remove(observer);
}
// 通知所有注冊(cè)的觀察者對(duì)象
public void nodifyObservers(String newState) {
for (Observer observer : mObservers) {
observer.update(newState);
}
}
}
ConcreteSubject.java
/**
* 具體目標(biāo)者
*/
public class ConcreteSubject extends Subject {
private String state;
public String getState() {
return state;
}
public void change(String newState) {
state = newState;
System.out.println("ConcreteSubject State:" + state);
//狀態(tài)發(fā)生改變,通知觀察者
nodifyObservers(state);
}
}
Observer.java
/**
* 觀察者
*/
public interface Observer {
void update(String state);
}
ConcreteObserver.java
/**
*具體觀察者
*/
public class ConcreteObserver implements Observer {
// 觀察者狀態(tài)
private String observerState;
@Override
public void update(String state) {
// 更新觀察者狀態(tài)智听,讓它與目標(biāo)狀態(tài)一致
observerState = state;
System.out.println("ConcreteObserver State :" + observerState);
}
}
test
public class MyClass {
public static void main(String[] args) {
// 創(chuàng)建目標(biāo)對(duì)象
ConcreteSubject concreteSubject = new ConcreteSubject();
// 創(chuàng)建觀察者對(duì)象
Observer observer = new ConcreteObserver();
// 將觀察者對(duì)象注冊(cè)到目標(biāo)對(duì)象上
concreteSubject.attach(observer);
// 改變目標(biāo)對(duì)象的狀態(tài)
concreteSubject.change("I change");
}
}
運(yùn)行結(jié)果
模式分析
觀察者模式描述了如何建立對(duì)象與對(duì)象之間的依賴關(guān)系袱院,如何構(gòu)造滿足這種需求的系統(tǒng)。
這一模式中的關(guān)鍵對(duì)象是觀察目標(biāo)和觀察者瞭稼,一個(gè)目標(biāo)可以有任意數(shù)目的與之相依賴的觀察者,一旦目標(biāo)的狀態(tài)發(fā)生改變腻惠,所有的觀察者都將得到通知环肘。
作為對(duì)這個(gè)通知的響應(yīng),每個(gè)觀察者都將即時(shí)更新自己的狀態(tài)集灌,以與目標(biāo)狀態(tài)同步悔雹,這種交互也稱為發(fā)布-訂閱(publish-subscribe)。目標(biāo)是通知的發(fā)布者欣喧,它發(fā)出通知時(shí)并不需要知道誰是它的觀察者腌零,可以有任意數(shù)目的觀察者訂閱它并接收通
觀察模式的優(yōu)點(diǎn)
觀察者模式可以實(shí)現(xiàn)表示層和數(shù)據(jù)邏輯層的分離,并定義了穩(wěn)定的消息更新傳遞機(jī)制唆阿,抽象了更新接口益涧,使得可以有各種各樣不同的表示層作為具體觀察者角色。
觀察者模式在觀察目標(biāo)和觀察者之間建立一個(gè)抽象的耦合驯鳖。
觀察者模式支持廣播通信闲询。
觀察者模式符合“開閉原則”的要求。
觀察模式的缺點(diǎn)
如果一個(gè)觀察目標(biāo)對(duì)象有很多直接和間接的觀察者的話浅辙,將所有的觀察者都通知到會(huì)花費(fèi)很多時(shí)間扭弧。
如果在觀察者和觀察目標(biāo)之間有循環(huán)依賴的話,觀察目標(biāo)會(huì)觸發(fā)它們之間進(jìn)行循環(huán)調(diào)用记舆,可能導(dǎo)致系統(tǒng)崩潰鸽捻。
觀察者模式?jīng)]有相應(yīng)的機(jī)制讓觀察者知道所觀察的目標(biāo)對(duì)象是怎么發(fā)生變化的,而僅僅只是知道觀察目標(biāo)發(fā)生了變化。