系列文章
【設(shè)計(jì)模式】七大設(shè)計(jì)原則
【設(shè)計(jì)模式】第一章:?jiǎn)卫J?br>【設(shè)計(jì)模式】第二章:工廠模式
【設(shè)計(jì)模式】第三章:建造者模式
【設(shè)計(jì)模式】第四章:原型模式
【設(shè)計(jì)模式】第五章:適配器模式
【設(shè)計(jì)模式】第六章:裝飾器模式
【設(shè)計(jì)模式】第七章:代理模式
【設(shè)計(jì)模式】第八章:橋接模式
【設(shè)計(jì)模式】第九章:外觀模式 / 門(mén)面模式
【設(shè)計(jì)模式】第十章:組合模式
【設(shè)計(jì)模式】第十一章:享元模式
【設(shè)計(jì)模式】第十二章:觀察者模式
【設(shè)計(jì)模式】第十三章:模板方法模式
【設(shè)計(jì)模式】第十四章:策略模式
【設(shè)計(jì)模式】第十五章:責(zé)任鏈模式
【設(shè)計(jì)模式】第十六章:迭代器模式
【設(shè)計(jì)模式】第十七章:狀態(tài)模式
【設(shè)計(jì)模式】第十八章:備忘錄模式
【設(shè)計(jì)模式】第十九章:訪問(wèn)者模式
【設(shè)計(jì)模式】第二十章:解釋器模式
【設(shè)計(jì)模式】第二十一章:命令模式
【設(shè)計(jì)模式】第二十二章:中介者模式
一、定義
摘自百度百科: 觀察者模式(有時(shí)又被稱為模型(Model)-視圖(View)模式、源-收聽(tīng)者(Listener)模式或從屬者模式)是如那件設(shè)計(jì)模式的一種。在此種模式中,一個(gè)目標(biāo)物件管理所有相依于它的觀察者物件,并且在它本身的狀態(tài)改變時(shí)主動(dòng)發(fā)出通知。這通常透過(guò)呼叫各觀察者所提供的方法來(lái)實(shí)現(xiàn)。此種模式通常被用來(lái)實(shí)現(xiàn)事件處理系統(tǒng)。
二、角色分類
目標(biāo)角色(Subject)
被觀察者,其為被觀察的對(duì)象,可以是接口、抽象類或具體的類,但是因?yàn)楹芏嗲闆r下容易和其他模式混合使用,所以一般使用抽象類的情況多一些
具體目標(biāo)角色(Concrete Subject)
其為目標(biāo)角色的子類,通常它會(huì)包括經(jīng)常發(fā)生改變的數(shù)據(jù),當(dāng)它的狀態(tài)發(fā)生改變時(shí)會(huì)向它的各個(gè)觀察者發(fā)送通知。同時(shí)它還可以實(shí)現(xiàn)在目標(biāo)類中定義的抽象業(yè)務(wù)邏輯方法,如果無(wú)須擴(kuò)展目標(biāo)類,則具體目標(biāo)類可以省略
抽象觀察者角色(Observer)
觀察目標(biāo),并對(duì)觀察目標(biāo)的改變做出反應(yīng),一般將其定義為接口,聲明了更新數(shù)據(jù)的方法
具體觀察者(Concrete Observer)
在具體觀察者中維護(hù)一個(gè)指向具體目標(biāo)對(duì)象的引用,它存儲(chǔ)具體觀察者的有關(guān)狀態(tài),這些狀態(tài)需要和具體目標(biāo)的狀態(tài)保持一致;它實(shí)現(xiàn)了在抽象觀察者 中定義的更新數(shù)據(jù)的方法
客戶角色(Client)
具體調(diào)用方法的角色
三、實(shí)現(xiàn)方式
UML圖
具體實(shí)現(xiàn)
觀察者角色(Observer)
public interface Observer {
public void update();
}
目標(biāo)角色(Subject)
public abstract class Subject {
private Vector<Observer> obs = new Vector<>();
/**
* 添加觀察者
*/
public void addObserver(Observer obs) {
this.obs.add(obs);
}
/**
* 移除觀察者
*/
public void delObserver(Observer obs) {
this.obs.remove(obs);
}
/**
* 通知觀察者
*/
protected void notifyObserver() {
obs.forEach(any -> any.update());
}
/**
* 其他業(yè)務(wù)
*/
public abstract void doSomething();
}
具體目標(biāo)角色(Concrete Subject)
public class ConcreteSubject extends Subject {
public void doSomething() {
System.out.println("目標(biāo)角色發(fā)生改變");
this.notifyObserver();
}
}
具體觀察者角色(Concrete Observer)
public class ConcreteObserverA implements Observer {
public void update() {
System.out.println("觀察者A收到目標(biāo)角色改變事件");
}
}
public class ConcreteObserverB implements Observer {
public void update() {
System.out.println("觀察者B收到目標(biāo)角色改變事件");
}
}
客戶角色(Client)
public class Client {
public static void main() {
Subject sub = new ConcreteSubject();
sub.addObserver(new ConcreteObserverA());
sub.addObserver(new ConcreteObserverB());
sub.doSomething();
}
}
運(yùn)行結(jié)果
目標(biāo)角色發(fā)生改變
觀察者A收到目標(biāo)角色改變事件
觀察者B收到目標(biāo)角色改變事件
四、應(yīng)用場(chǎng)景
以下部分內(nèi)容摘自菜鳥(niǎo)教程
意圖: 定義對(duì)象間的一種一對(duì)多的依賴關(guān)系,當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí),所有依賴于它的對(duì)象都得到通知并被自動(dòng)更新。
主要解決: 一個(gè)對(duì)象狀態(tài)改變給其他對(duì)象通知的問(wèn)題,而且要考慮到易用和低耦合,保證高度的協(xié)作。
何時(shí)使用: 一個(gè)對(duì)象(目標(biāo)對(duì)象)的狀態(tài)發(fā)生改變,所有的依賴對(duì)象(觀察者對(duì)象)都將得到通知,進(jìn)行廣播通知。
如何解決: 使用面向?qū)ο蠹夹g(shù),可以將這種依賴關(guān)系弱化。
關(guān)鍵代碼: 在抽象類里有一個(gè) ArrayList 或 Vector 存放觀察者們。
應(yīng)用實(shí)例:
- 拍賣(mài)的時(shí)候,拍賣(mài)師觀察最高標(biāo)價(jià),然后通知給其他競(jìng)價(jià)者競(jìng)價(jià)。
- 西游記里面悟空請(qǐng)求菩薩降服紅孩兒,菩薩灑了一地水招來(lái)一個(gè)老烏龜,這個(gè)烏龜就是觀察者,他觀察菩薩灑水這個(gè)動(dòng)作。
使用場(chǎng)景:
- 一個(gè)抽象模型有兩個(gè)方面,其中一個(gè)方面依賴于另一個(gè)方面。將這些方面封裝在獨(dú)立的對(duì)象中使它們可以各自獨(dú)立地改變和復(fù)用。
- 一個(gè)對(duì)象的改變將導(dǎo)致其他一個(gè)或多個(gè)對(duì)象也發(fā)生改變,而不知道具體有多少對(duì)象將發(fā)生改變,可以降低對(duì)象之間的耦合度。
- 一個(gè)對(duì)象必須通知其他對(duì)象,而并不知道這些對(duì)象是誰(shuí)。
- 需要在系統(tǒng)中創(chuàng)建一個(gè)觸發(fā)鏈,A對(duì)象的行為將影響B(tài)對(duì)象,B對(duì)象的行為將影響C對(duì)象……,可以使用觀察者模式創(chuàng)建一種鏈?zhǔn)接|發(fā)機(jī)制。
注意事項(xiàng):
- JAVA 中已經(jīng)有了對(duì)觀察者模式的支持類。
- 避免循環(huán)引用。
- 如果順序執(zhí)行,某一觀察者錯(cuò)誤會(huì)導(dǎo)致系統(tǒng)卡殼,一般采用異步方式。
五、優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
- 觀察者和被觀察者是抽象耦合的。
- 建立一套觸發(fā)機(jī)制。
缺點(diǎn)
- 如果一個(gè)被觀察者對(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ā)生了變化。
推薦
關(guān)注博客和公眾號(hào)獲取最新文章文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-534037.html
Bummon’s Blog | Bummon’s Home | 公眾號(hào)文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-534037.html
到了這里,關(guān)于【設(shè)計(jì)模式】第十二章:觀察者模式詳解及應(yīng)用案例的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!