摘要:關(guān)鍵概念理解觀察者設(shè)計(jì)模式中主要區(qū)分兩個(gè)概念觀察者指觀察者對(duì)象,也就是消息的訂閱者被觀察者指要觀察的目標(biāo)對(duì)象,也就是消息的發(fā)布者。
原文首發(fā)于微信公眾號(hào):jzman-blog,歡迎關(guān)注交流!
最近補(bǔ)一下設(shè)計(jì)模式相關(guān)的知識(shí),關(guān)于觀察者設(shè)計(jì)模式主要從以下幾個(gè)方面來(lái)學(xué)習(xí),具體如下:
什么是觀察者設(shè)計(jì)模式
關(guān)鍵概念理解
通知觀察者的方式
觀察者模式的實(shí)現(xiàn)
觀察者模式的優(yōu)缺點(diǎn)
使用場(chǎng)景
下面來(lái)一張本節(jié)內(nèi)容的思維導(dǎo)圖,具體如下:
什么是觀察者設(shè)計(jì)模式觀察者模式(Observer)是軟件設(shè)計(jì)模式的一種,定義了對(duì)象之間一種一對(duì)多的關(guān)系,也就是當(dāng)一個(gè)對(duì)象數(shù)據(jù)發(fā)生變化時(shí),會(huì)通知與之依賴(lài)的其他對(duì)象,以相應(yīng)其數(shù)據(jù)變化,這種當(dāng)目標(biāo)對(duì)象數(shù)據(jù)發(fā)生變化時(shí),與之對(duì)應(yīng)的觀察者對(duì)象數(shù)據(jù)隨之發(fā)生變化的,具有一對(duì)多通知關(guān)系的設(shè)計(jì)模式叫做觀察者設(shè)計(jì)模式。
關(guān)鍵概念理解觀察者設(shè)計(jì)模式中主要區(qū)分兩個(gè)概念:
觀察者:指觀察者對(duì)象,也就是消息的訂閱者;
被觀察者:指要觀察的目標(biāo)對(duì)象,也就是消息的發(fā)布者。
通知觀察者的方式當(dāng)被被觀察者數(shù)據(jù)發(fā)生變化時(shí),主要通過(guò)兩種方式通知觀察者,具體如下:
推:消息以類(lèi)似廣播的形式通知觀察者,觀察者只能被動(dòng)、無(wú)條件接受;
拉:接收到被觀察者的通知,可以自主決定獲取消息。
觀察者模式的實(shí)現(xiàn)下面通過(guò)兩種方式實(shí)現(xiàn)觀察者設(shè)計(jì)模式的實(shí)現(xiàn),具體如下:
手寫(xiě)觀察者設(shè)計(jì)模式
Java API 提供的觀察者設(shè)計(jì)模式 使用 Java API 提供的 Observer 和 Observeable 實(shí)現(xiàn)觀察者模式
首先創(chuàng)建被觀察者,具體如下:
/** * 觀察者要觀察的目標(biāo)對(duì)象 * @author jzman */ public abstract class Subject { protected ArrayListobserverList = new ArrayList<>(); //表示觀察者對(duì)目標(biāo)對(duì)象(被觀察者)開(kāi)始觀察 public void registerObserver(Observer obs) { observerList.add(obs); } //表示取消某觀察者對(duì)目標(biāo)對(duì)象(被觀察者)的觀察 public void unRegisterObserver(Observer obs) { observerList.remove(obs); } //當(dāng)目標(biāo)對(duì)象(被觀察者)的狀態(tài)發(fā)生變化時(shí),及時(shí)更新觀察者的狀態(tài) public void notifyAllObserver(){ for (Observer observer : observerList) { observer.update(this); } } }
創(chuàng)建具體的被觀察者,具體如下:
/** * 具體的目標(biāo)對(duì)象(被觀察者) * @author jzman */ public class ConcreteSubject extends Subject{ private int state; public int getState() { return state; } public void setState(int state) { this.state = state; //當(dāng)數(shù)據(jù)發(fā)生變化時(shí)通知其他的觀察者 notifyAllObserver(); } }
然后,為了統(tǒng)一方便,定義觀察者接口,具體如下:
/** * 觀察者統(tǒng)一接口 * @author jzman */ public interface Observer { void update(Subject subject); }
然后,創(chuàng)建具體的觀察者,具體如下:
/** * 具體的觀察者 * @author jzman */ public class ConcreteObserver implements Observer{ private int state; public int getState() { return state; } public void setState(int state) { this.state = state; } @Override public void update(Subject subject) { //獲取目標(biāo)對(duì)象的數(shù)據(jù)變化,同時(shí)更新當(dāng)前觀察者 ConcreteSubject concreteSubject = (ConcreteSubject)subject; state = concreteSubject.getState(); } }
最后,測(cè)試觀察者設(shè)計(jì)模式,具體如下:
/** * Main * @author jzman */ public class Client { public static void main(String[] args) { //創(chuàng)建具體的目標(biāo)對(duì)象(被觀察者) ConcreteSubject concreteSubject = new ConcreteSubject(); //創(chuàng)建多個(gè)具體的觀察者 ConcreteObserver obs1 = new ConcreteObserver(); ConcreteObserver obs2 = new ConcreteObserver(); ConcreteObserver obs3 = new ConcreteObserver(); //讓觀察者觀察目標(biāo)對(duì)象(被觀察者)的數(shù)據(jù)變化 concreteSubject.observerList.add(obs1); concreteSubject.observerList.add(obs2); concreteSubject.observerList.add(obs3); //改變某個(gè)目標(biāo)對(duì)象(被觀察者)的數(shù)據(jù) concreteSubject.setState(10); //觀察者數(shù)據(jù)是否與被觀察者數(shù)據(jù)變化一致 System.out.println("觀察者obs1:"+obs1.getState()); System.out.println("觀察者obs2:"+obs2.getState()); System.out.println("觀察者obs3:"+obs3.getState()); } }
顯然,執(zhí)行結(jié)果肯定如下:
觀察者obs1:10 觀察者obs2:10 觀察者obs3:10
通過(guò)對(duì)目標(biāo)對(duì)象數(shù)據(jù)的改變,更新了與之相對(duì)應(yīng)的觀察者的數(shù)據(jù),實(shí)現(xiàn)了消息的訂閱和發(fā)送。
2. Java API 提供的觀察者設(shè)計(jì)模式Java API 提供的觀察者設(shè)計(jì)模式主要通過(guò) Observer 和 Observeable 來(lái)實(shí)現(xiàn),首先創(chuàng)建一個(gè)類(lèi)繼承 Observeable 作為被觀察者,具體如下:
/** * 被觀察者(目標(biāo)對(duì)象) * @author jzman */ public class ConcreteSubject extends Observable{ private int state; public int getState() { return state; } public void setState(int state) { this.state = state; //表示數(shù)據(jù)已經(jīng)發(fā)生變化 setChanged(); //具體的目標(biāo)對(duì)象數(shù)據(jù)變化的時(shí)候通知觀察者 notifyObservers(state); } }
然后,創(chuàng)建一個(gè)類(lèi)繼承 Observer 作為觀察者,具體如下:
/** * 觀察者 * @author jzman */ public class ConcreteObserver implements Observer{ private int state; public int getState() { return state; } public void setState(int state) { this.state = state; } @Override public void update(Observable arg0, Object arg1) { ConcreteSubject concreteSubject = (ConcreteSubject) arg0; //根據(jù)目標(biāo)對(duì)象(被觀察者)的數(shù)據(jù)變化更新當(dāng)前觀察者的數(shù)據(jù) this.state = concreteSubject.getState(); } }
最后,測(cè)試觀察者設(shè)計(jì)模式,具體如下:
/** * 測(cè)試觀察者設(shè)計(jì)模式 * @author jzman */ public class Client { public static void main(String[] args) { ConcreteSubject concreteSubject = new ConcreteSubject(); ConcreteObserver obs1 = new ConcreteObserver(); ConcreteObserver obs2 = new ConcreteObserver(); ConcreteObserver obs3 = new ConcreteObserver(); concreteSubject.addObserver(obs1); concreteSubject.addObserver(obs2); concreteSubject.addObserver(obs3); concreteSubject.setState(100); System.out.println("觀察者obs1:"+obs1.getState()); System.out.println("觀察者obs2:"+obs2.getState()); System.out.println("觀察者obs3:"+obs3.getState()); } }
顯然,執(zhí)行結(jié)果肯定如下:
觀察者obs1:100 觀察者obs2:100 觀察者obs3:100觀察者模式的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):觀察者與被觀察者抽象耦合,可定義一種穩(wěn)定的消息觸發(fā)機(jī)制。
缺點(diǎn):如果被觀察者有多個(gè)間接的觀察者,消息的傳遞將消耗更多時(shí)間,如果觀察者與被觀察者之間循環(huán)依賴(lài),最終會(huì)導(dǎo)致系統(tǒng)崩潰。
使用場(chǎng)景觀察者設(shè)計(jì)模式在開(kāi)發(fā)中使用比較廣泛,主要有以下幾個(gè)場(chǎng)景,具體如下:
如游戲、聊天等過(guò)程中消息的從服務(wù)端轉(zhuǎn)發(fā)給客戶(hù)端的過(guò)程
Android 中的廣播機(jī)制以及 ListView 中通知數(shù)據(jù)發(fā)生變化時(shí)也是觀察者設(shè)計(jì)模式
訂閱類(lèi)相關(guān)的系統(tǒng),如當(dāng)訂閱的主題有更新,訂閱者就會(huì)同步訂閱的文章。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/74431.html
摘要:觀察者模式定義設(shè)計(jì)模式中對(duì)的定義一個(gè)對(duì)象稱(chēng)為維持一系列依賴(lài)于它觀察者的對(duì)象,將有關(guān)狀態(tài)的任何變更自動(dòng)通知給它們。如圖模式比較觀察者模式則多了一個(gè)類(lèi)似于話(huà)題調(diào)度中心的流程,發(fā)布者和訂閱者解耦。 Obeserver(觀察者)模式 定義 《js設(shè)計(jì)模式》中對(duì)Observer的定義:一個(gè)對(duì)象(稱(chēng)為subject)維持一系列依賴(lài)于它(觀察者)的對(duì)象,將有關(guān)狀態(tài)的任何變更自動(dòng)通知給它們。 《設(shè)計(jì)模...
摘要:觀察者模式的使用場(chǎng)景比如你微博關(guān)注了一個(gè)人,那么這個(gè)人發(fā)布的微博就會(huì)推送到你這。 Java設(shè)計(jì)模式之觀察者模式 一直想寫(xiě)一篇學(xué)習(xí)觀察者模式的總結(jié)沒(méi)有契機(jī),今天學(xué)習(xí)阻塞隊(duì)列的原理時(shí)候看到在實(shí)現(xiàn)生產(chǎn)者消費(fèi)者的時(shí)候用到了通知模式,就是所謂的觀察者模式,正好順便整理一下。 1. 簡(jiǎn)介 觀察者模式定義對(duì)象間的一種一對(duì)多的依賴(lài)關(guān)系,當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí),所有依賴(lài)于它的對(duì)象都得到通知并被自動(dòng)更...
摘要:概念觀察者模式屬于行為模式,是定義對(duì)象間的一種一對(duì)多的依賴(lài)關(guān)系,以便當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí),所有依賴(lài)于它的對(duì)象都得到通知并自動(dòng)刷新。觀察者模式符合接口隔離原則,實(shí)現(xiàn)了對(duì)象之間的松散耦合。 概念 觀察者模式屬于行為模式,是定義對(duì)象間的一種一對(duì)多的依賴(lài)關(guān)系,以便當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí),所有依賴(lài)于它的對(duì)象都得到通知并自動(dòng)刷新。 當(dāng)一個(gè)對(duì)象狀態(tài)發(fā)生改變后,會(huì)影響到其他幾個(gè)對(duì)象的改變,這...
摘要:最近在學(xué)的設(shè)計(jì)模式,看到了觀察者模式,在此寫(xiě)下一點(diǎn)理解問(wèn)題假如一個(gè)小販,他把產(chǎn)品的價(jià)格提升了,不同的消費(fèi)者會(huì)對(duì)此產(chǎn)生不同的反應(yīng)。 最近在學(xué)php 的設(shè)計(jì)模式, 看到了觀察者模式,在此寫(xiě)下一點(diǎn)理解: 問(wèn)題: 假如一個(gè)小販, 他把產(chǎn)品的價(jià)格提升了, 不同的消費(fèi)者會(huì)對(duì)此產(chǎn)生不同的反應(yīng)。一般的編程模式無(wú)非是獲取提升的價(jià)格,然后獲取所有的消費(fèi)者,再循環(huán)每個(gè)消費(fèi)者, 不同的消費(fèi)者根據(jù)價(jià)格漲幅...
摘要:監(jiān)聽(tīng)模式又名觀察者模式發(fā)布訂閱模式源監(jiān)聽(tīng)器模式,模式的核心是設(shè)計(jì)時(shí)要區(qū)分誰(shuí)是被觀察者,誰(shuí)是觀察者。 監(jiān)聽(tīng)模式 又名觀察者模式、發(fā)布/訂閱模式、源-監(jiān)聽(tīng)器(Source/Listener)模式,模式的核心是:設(shè)計(jì)時(shí)要區(qū)分誰(shuí)是被觀察者,誰(shuí)是觀察者。被觀察者至少有三個(gè)方法,添加觀察者、刪除觀察者、監(jiān)聽(tīng)目標(biāo)變化并通知觀察者;觀察者這至少包含一個(gè)方法,當(dāng)接收到被觀察者的通知時(shí),做出相應(yīng)的處理(即...
閱讀 3557·2021-11-18 10:07
閱讀 1651·2021-11-04 16:08
閱讀 1602·2021-11-02 14:43
閱讀 1159·2021-10-09 09:59
閱讀 937·2021-09-08 10:43
閱讀 1202·2021-09-07 09:59
閱讀 1048·2019-12-27 11:56
閱讀 1166·2019-08-30 15:56