java观察者模式本质_6.[研磨设计模式笔记]观察者模式
1.定義
定義對象間的一種一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴于它的對象都得到通知并自動更新。
2.解決問題
——訂閱報紙
看起來訂閱者是直接根有據打交道,但實際上,訂閱者的訂閱數據是被郵寄傳遞到報社,當報社出了報紙,報社按訂閱信息交給郵局,郵局在代為發送到訂閱者手里。在整個過程中,郵局起到一個中轉的作用。
使用觀察者模式來解決問題public class Subject {
private List readers = new ArrayList();
public void attach(Observer reader) {
readers.add(reader);
}
public void detach(Observer observer) {
readers.remove(observer);
}
protected void notifyObservers() {
for (Observer reader : readers)
reader.update(this);
}
}
public class NewsPaper extends Subject {
private String content;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
super.notifyObservers();
}
}
public interface Observer {
public void update(Subject subject);
}
public class Reader implements Observer {
private String name;
public void update(Subject subject) {
name = ((NewsPaper)subject).getContent();
System.out.println(name);
}
}
public class Client {
public static void main(String[] args) {
// 創建一個報紙,作為目標
NewsPaper subject = new NewsPaper();
// 創建一個讀者
Reader reader1 = new Reader();
Reader reader2 = new Reader();
// 注冊訂閱者
subject.attach(reader1);
subject.attach(reader2);
// 要出報紙啦
subject.setContent("New");
}
}
3.模式講解
上述問題中訂閱者最關心的問題時是何時能收到最新處的報紙,但要是報紙出版的時間不固定怎么辦?進一步抽象這個問題:當一個對象的狀態發生改變的時候,如果讓依賴于它的所有對象得到通知,并進行相應的處理呢?
解決思路
這是一個典型一對多的對象關系,一個報紙對象,有很多個訂閱者對象來訂閱,當報紙出版的時候,也就是報紙對象改變的時候。觀察者模式處理這種問題時,把這多個訂閱者稱為觀察者:Observer,多個觀察者觀察的對象稱為目標:Subject。
一個目標可以有任意多個觀察者獨享,一旦目標的狀態發生改變,所有注冊的觀察者都會得到通知,然后各個觀察者會對通知做出相應的響應,執行相應的業務功能處理,并使自己的狀態與目標狀態保持一致。
示例代碼public class Subject {
// 用來保存注冊的觀察者對象
private List observers = new ArrayList();
// 注冊觀察者對象
public void attach(Observer observer) {
observers.add(observer);
}
// 刪除觀察者對象
public void detach(Observer observer) {
observers.remove(observer);
}
// 通知所有注冊的觀察者對象
protected void notifyObservers() {
for (Observer observer : observers)
observer.update(this);
}
}
public class ConcreteSubject extends Subject {
private String subjectState;
public String getSubjectState() {
return subjectState;
}
public void setSubjectState(String subjectState) {
this.subjectState = subjectState;
// 狀態改變了,通知各個觀察者
this.notifyObservers();
}
}
public interface Observer {
public void update(Subject subject);
}
public class ConcreteObserver implements Observer {
private String observerState;
public void update(Subject subject) {
// 可能需要更新觀察者狀態,使其與目標的狀態保持一致
observerState = ((ConcreteSubject) subject).getSubjectState();
}
}
應用范圍
按照模式的定義,目標和觀察者之間是典型的一對多關系。但如果觀察者只有一個,也是可以的;同樣,一個觀察者也可以觀察多個目標。
單向依賴
在觀察者模式中,觀察者和目標是單向依賴,只有觀察者依賴于目標,而目標不能依賴與觀察者。
觀察者模式調用順序示意圖
在使用觀察者模式時,分為兩個階段:
第一個階段是準備階段,即維護目標和觀察者關系的階段;
第二階段是實際運行階段。
推模式和拉模式
推模式:目標對象主動向觀察者推送目標的詳細信息,不管觀察者是否需要,推送的信息通常是目標對象的全部或部分數據,相當于廣播通信。
拉模式:目標對象在通知觀察者的時候,只傳遞少量信息,如果觀擦或者需要更具體的信息,由觀察者主動到目標對象中獲取,相當于觀察者從目標對象中拉數據。
Java觀察者模式
java.util包里有一個Observable類,還有一個接口Observer,其中定義了update方法,就是觀察者接口。public class NewsPaper extends java.util.Observable {
private String content;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
// 注意在Java中Observer模式的時候,下邊這句不可少
this.setChanged();
// 然后主動通知,這里用的推模式
this.notifyObservers(this.content);
}
}
public class Reader implements java.util.Observer {
private String name;
public void update(Observable o, Object obj) {
// 這是采用推的方式
System.out.println(name + obj);
// 這是采用拉的方式
System.out.println(name + ((NewsPaper) o).getContent());
}
}
public class Client {
public static void main(String[] args) {
// 創建一個報紙,作為目標
NewsPaper subject = new NewsPaper();
// 創建一個讀者
Reader reader1 = new Reader();
Reader reader2 = new Reader();
// 注冊訂閱者
subject.addObserver(reader1);
subject.addObserver(reader2);
// 要出報紙啦
subject.setContent("New");
}
}
適配器模式的優缺點:
優點:實現了觀察者和目標之間的抽象耦合,實現了動態聯動,支持廣播通信
缺點:可能會引起無謂的操作
4.思考
觀察者模式的本質是:觸發聯動
當修改目標對象的狀態時,就會觸發相應的通知,然后會循環調用所有注冊的觀擦或者對象的相應方法,其實就相當于聯動調用這些觀察者的方法。
何時選用適配器模式
當一個抽象模型有兩個方面,其中一個方面的操作依賴于另一個方面的狀態變化,可以選用觀察者模式;
如果在更改一個對象的時候,需要同時連帶改變其他的喜愛那個,而且不知道究竟應該有多少對象需要被連帶改變,可以選用觀察者模模式;
當一個對象必須通知其他對象,但是有希望這個對象和其他被通知的對象是松散耦合的,即這個對象其實不想知道具體被通知的對象,可以選用觀察者模式。
說明:筆記內容摘自《研磨設計模式》陳臣,王斌
總結
以上是生活随笔為你收集整理的java观察者模式本质_6.[研磨设计模式笔记]观察者模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hystrix原理_面试必问的Sprin
- 下一篇: 你觉得外观模式和代理模式的联系和区别是什