觀察者模式(Observer Pattern)

觀察者模式(Observer Pattern)

定義

  • 觀察者模式定義了一種一對多的依賴關系,讓多個觀察者對象同時監聽某一個主題對象。這個主題對象在狀態發生變化時,會通知所有觀察者對象,使它們能夠自動更新自己。
  • 別名:模型-視圖模式、源-收聽者模式、從屬者模式、發布-訂閱模式。
  • 觀察者模式通過解耦觀察者和被觀察者,使得它們可以獨立地變化和復用。
  • 是行為型設計模式。

適用場景

  1. 當一個抽象模型包含兩個方面內容,其中一個方面依賴于另一個方面;
  2. 其他一個或多個對象的變化依賴于另一個對象的變化;
  3. 實現類似于廣播機制的功能,無需知道具體收聽者,只需分發廣播,系統中感興趣的對象會自動接收該廣播;
  4. 多層級嵌套使用,形成一種鏈式觸發機制,使得事件具備跨域(跨越兩種觀察者類型)通知。

標準示例

在這里插入圖片描述

觀察者模式通常包含以下幾個角色:
Subject(主題/被觀察者):維護一個觀察者列表,并提供注冊、移除和通知觀察者的方法。
Observer(觀察者):定義一個更新接口,以便在得到主題通知時更新自己。
ConcreteSubject(具體主題):具體的被觀察者,在內部狀態改變時,通知所有注冊的觀察者。
ConcreteObserver(具體觀察者):實現抽象觀察者的定義,以便在得到主題狀態更改通知時更新自身。

示例代碼:
ISubject 抽象主題

/*** 抽象主題*/
public interface ISubject<E> {boolean attach(IObserver<E> observer);boolean detach(IObserver<E> observer);void notify(E event);
}

IObserver 抽象觀察者

/*** 抽象觀察者*/
public interface IObserver<E> {/*** 更新* @param event*/void update(E event);
}

ConcreteSubject 具體主題

/*** 具體主題*/
public class ConcreteSubject<E> implements ISubject<E>{private List<IObserver<E>> observers = new ArrayList<IObserver<E>>();public boolean attach(IObserver<E> observer) {return !this.observers.contains(observer) && this.observers.add(observer);}public boolean detach(IObserver<E> observer) {return this.observers.remove(observer);}public void notify(E event) {for(IObserver<E> observer:observers){observer.update(event);}}
}

ConcreteObserver 具體觀察者

public class ConcreteObserver<E> implements IObserver<E>{public void update(E event) {System.out.println(this.getClass().getSimpleName() + " receive event : " + event);}
}

客戶端調用代碼:

public class ClientTest {public static void main(String[] args) {//被觀察者ISubject<String> subject = new ConcreteSubject<String>();//觀察者IObserver<String> observer = new ConcreteObserver<String>();//被觀察者注冊subject.attach(observer);//通知subject.notify("hello");}
}

輸出執行結果:

ConcreteObserver receive event : hello

接下來,我們使用jdk中提供的觀察者模式接口來實現一個如下場景:
明星發聲,粉絲關注并收聽。

Idol 明星主題抽象類

/*** 抽象主題者——偶像*/
public interface Idol {void posting(String message);
}

ConcreteIdol 明星主題具體類

/*** 具體偶像類*/
@Data
public class ConcreateIdol extends Observable implements Idol{private String name;public ConcreateIdol(String name){this.name = name;}public void posting(String message) {System.out.println("【明星發布】 "+message);setChanged();notifyObservers(message);}
}

Fans粉絲具體類

/*** 觀察者*/
public class Fans implements Observer {private String idol;private String selfName;public Fans(String idol,String selfName){this.idol = idol;this.selfName = selfName;}public void update(Observable o, Object arg) {System.out.println("【粉絲"+this.selfName+"收到通知】 " +  "收到偶像消息:"+ arg);}
}

JDK中,java.util.Observable 類,相當于IObserver的存在,所以,我們的Fans類,只要繼承Observable即可。在發布的被監聽方法中,只要調用如下兩個方法,可以實現發布。

setChanged();
notifyObservers();

而監聽者實現類 Fans,只需要實現jdk中的 java.util.Observer 接口。其中的 update 方法,即為訂閱到發布消息后的回調方法。
ClientTest 客戶端調用類:

public class ClientTest {public static void main(String[] args) {ConcreateIdol zhazhahui = new ConcreateIdol("渣渣輝");zhazhahui.addObserver(new Fans(zhazhahui.getName(),"小明明"));zhazhahui.addObserver(new Fans(zhazhahui.getName(),"小甜甜"));String message = "大家好,我是"+zhazhahui.getName()+",歡迎體驗我代言的新版砍怪看到手抽筋大型即使PK古裝仙俠網游!";zhazhahui.posting(message);}
}

執行后的結果輸出為:

【明星發布】 大家好,我是渣渣輝,歡迎體驗我代言的新版砍怪看到手抽筋大型即使PK古裝仙俠網游!
【粉絲小甜甜收到通知】 收到偶像消息:大家好,我是渣渣輝,歡迎體驗我代言的新版砍怪看到手抽筋大型即使PK古裝仙俠網游!
【粉絲小明明收到通知】 收到偶像消息:大家好,我是渣渣輝,歡迎體驗我代言的新版砍怪看到手抽筋大型即使PK古裝仙俠網游!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/42068.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/42068.shtml
英文地址,請注明出處:http://en.pswp.cn/web/42068.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

鼠標宏怎么設置?6款鼠標自動點擊器強推,游戲玩家專用!(2024全)

隨著電子游戲和日常應用的不斷發展&#xff0c;我們經常會遇到一些重復性的任務或操作。而在這種情況下&#xff0c;鼠標宏以其自動化的特點成為了許多玩家和使用者的利器之一。如果你正在尋找如何設置鼠標宏來簡化操作并提高效率&#xff0c;那么你來對地方了。在本文中&#…

【Java]認識泛型

包裝類 在Java中&#xff0c;由于基本類型不是繼承自Object&#xff0c;為了在泛型代碼中可以支持基本類型&#xff0c;Java給每個基本類型都對應了一個包裝類型。 除了 Integer 和 Character&#xff0c; 其余基本類型的包裝類都是首字母大寫。 泛型 泛型是在JDK1.5引入的…

ASAN排查程序中內存問題使用總結

簡介 谷歌有一系列Sanitizer工具&#xff0c;可用于排查程序中內存相關的問題。常用的Sanitizer工具包括&#xff1a; Address Sanitizer&#xff08;ASan&#xff09;&#xff1a;用于檢測內存使用錯誤。Leak Sanitizer&#xff08;LSan&#xff09;&#xff1a;用于檢測內存…

【9-2:RPC設計】

RPC 1. 基礎1.1 定義&特點1.2 具體實現框架1.3 應用場景2. RPC的關鍵技術點&一次調用rpc流程2.1 RPC流程流程兩個網絡模塊如何連接的呢?其它特性RPC優勢2.2 序列化技術序列化方式PRC如何選擇序列化框架考慮因素2.3 應用層的通信協議-http什么是IO操作系統的IO模型有哪…

數據結構第14節 加權圖

加權圖是在圖論中一種更為復雜的圖結構&#xff0c;它擴展了無向圖和有向圖的概念&#xff0c;通過給圖中的邊附加一個數值來表示邊的某種屬性&#xff0c;如成本、距離、容量或相似度等。這個數值被稱為邊的“權重”。 定義 加權圖可以被形式化地定義為一個三元組 ( G (V, …

Vortex GPGPU的硬件設計和代碼結構分析

文章目錄 前言一、GPGPU是什么&#xff1f;1.1 GPU和GPGPU之間的差異1.2 GPU和CPU之間的集成方式1.3 GPU包含什么&#xff08;列舉和VMIPS向量體系結構的差異&#xff09; 二、Vortex GPGPU是什么&#xff1f;2.1 Vortex GPGPU的技術邊界和驗證環境2.2 Vortex GPGPU的指令集設計…

安卓穩定性之crash詳解

目錄 前言一、Crash 的基本原理二、Crash 分析思路三、實例分析四、預防措施五、參考鏈接 前言 在開發和測試 Android 應用程序時&#xff0c;遇到應用程序崩潰是很常見的情況。 Android 崩潰指的是應用程序因為異常或錯誤而無法正常執行&#xff0c;并且導致應用強制關閉。 一…

p11函數和遞歸

遞歸與迭代 求n的階乘。&#xff08;不考慮溢出&#xff09; int Fac1(int n) {int i0;int ret1;for(i1;i<n;i){ret*i;}return ret; } int main(){//求n的階乘int n0;int ret0;scanf("%d",&n);retFac1(n);printf("%d\n",ret);return 0; } int Fac…

什么是激光導航和視覺導航技術

激光導航和視覺導航技術是現代導航系統中的兩種重要技術&#xff0c;它們在多個領域&#xff0c;如掃地機器人、無人機、機器人導航等中都有廣泛應用。以下是對這兩種技術的詳細介紹&#xff1a; 一、激光導航技術 1. 定義與原理 激光導航技術是一種利用激光束進行精確測量和…

ChatGPT:||是短路運算符,那么|、、是什么?

ChatGPT&#xff1a;||是短路運算符&#xff0c;那么|、&、&&是什么? 在Java中&#xff0c;邏輯運算符&&和||是短路邏輯運算符&#xff0c;而&和|是非短路邏輯運算符。 && 和 || 是短路邏輯運算符。當使用這些運算符時&#xff0c;如果第一個…

解決 Docker 容器鏡像拉取難題:全面指南

一、引言 在使用 Docker 容器的過程中&#xff0c;經常會遇到鏡像拉取慢甚至無法下載的問題&#xff0c;這給開發和部署工作帶來了不小的困擾。本文將深入探討這一問題的原因&#xff0c;并提供多種有效的解決方案。 二、問題原因分析 網絡限制 本地網絡帶寬不足或存在網絡擁…

unity知識點 專項四 一文徹底說清楚(錨點(anchor)、中心點(pivot)、位置(position)之間的關系)

一 概述 想要使UI控件在屏幕中達到正確的顯示效果&#xff0c;比如自適應屏幕尺寸、固定邊距等等&#xff0c;首先要理清楚幾個基本概念和設置&#xff1a;錨點(anchor)、中心點(pivot)、位置(position)、UI縮放模式、父物件的transform設置 二 Anchor、Pivot與Position 2…

網絡連接線相關問題

問題1&#xff1b; 直通線為什么兩頭都是T568B&#xff1f;是否可以兩臺T5568A&#xff1f;或者任意線序&#xff0c;只需兩頭一致&#xff1f; 不行&#xff0c;施工規范規定。&#xff08;原因&#xff1b;網線最長距離100m&#xff0c;實際用起來要把網線包管&#xff0c;走…

【分布式系統】Filebeat+Kafka+ELK 的服務部署

目錄 一.實驗準備 二.配置部署 Filebeat 三.配置Logstash 四.驗證 一.實驗準備 結合之前的博客中的實驗 主機名ip地址主要軟件es01192.168.80.101ElasticSearches02192.168.80.102ElasticSearches03192.168.80.103ElasticSearch、Kibananginx01192.168.80.104nginx、Logs…

iperf3: error - unable to connect to server: No route to host

1.確認iperf3版本是否統一。 2.確認防火墻是否關閉。 關閉防火墻 : systemctl stop firewalld 查看防火墻狀態: systemctl status firewalld 3.重新建起鏈接

Java進階----接口interface

接口 接口概述 接口是一種規范&#xff0c;使用接口就代表著要在程序中制定規范. 制定規范可以給不同類型的事物定義功能&#xff0c;例如&#xff1a; 利用接口&#xff0c;給飛機、小鳥制定飛行規范&#xff0c;讓其都具備飛行的功能&#xff1b;利用接口&#xff0c;給鼠…

SMU Summer 2024 Contest Round 1

A.Hcode OnlineJudge 給出一個N面骰子和整數K&#xff0c;擲出1-N之間的每個數的概率相同&#xff0c;每次擲出一次&#xff0c;記為成績&#xff0c;若成績小于K&#xff0c;則開始拋硬幣&#xff0c;硬幣朝上則數翻倍&#xff0c;反之則為0&#xff0c;概率都為0.5。當數大于…

自動駕駛算法———車道檢測(一)

“ 在本章中&#xff0c;我將指導您構建一個簡單但有效的車道檢測管道&#xff0c;并將其應用于Carla 模擬器中捕獲的圖像。管道將圖像作為輸入&#xff0c;并產生車道邊界的數學模型作為輸出。圖像由行車記錄儀&#xff08;固定在車輛擋風玻璃后面的攝像頭&#xff09;捕獲。…

【ZIP壓縮大揭秘】輕松掌握ZIP分卷壓縮包的高效解壓秘籍!

在這個信息爆炸的時代&#xff0c;文件大小常常成為我們分享與存儲的絆腳石。幸運的是&#xff0c;ZIP分卷壓縮技術如同一把鑰匙&#xff0c;巧妙地將龐然大物分解成小巧易管理的部分。但面對這一串分卷壓縮包&#xff0c;你是否也曾迷茫于如何高效解壓&#xff0c;恢復文件的完…

解碼Python字符串:‘r‘、‘b‘、‘u‘和‘f‘前綴的全面指南

&#x1f4d6; 正文 1 字符串前加’r’ 表示原始字符串&#xff0c;消除轉義 print(abc\nde) # abc # deprint(rabc\nde) # abc\nde在下面這個列子中&#xff0c;如果不在路徑字符串前面加r那么&#xff0c;路徑中的空格就會出現問題 print(rD:\01 programming\09python\py…