日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java描述设计模式(11):观察者模式

發布時間:2025/3/16 java 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java描述设计模式(11):观察者模式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文源碼:GitHub·點這里 || GitEE·點這里

一、觀察者模式

1、概念描述

觀察者模式是對象的行為模式,又叫發布-訂閱(Publish/Subscribe)模式。觀察者模式定義了一種一對多的依賴關系,讓多個觀察者對象同時監聽某一個主題對象,主題對象在狀態發生變化時,會通知所有觀察者對象。Redis和常用消息中間件的發布訂閱模式,都是基于該原理實現。

2、核心角色

  • 抽象主題角色

抽象主題角色把所有對觀察者對象的統一聚集管理,每個主題都可以有一個或多個觀察者。抽象主題提供一個接口,可以增加和刪除觀察者對象,抽象主題角色又叫做抽象被觀察者(Observable)角色。

  • 具體主題角色

將有關狀態存入具體觀察者對象;在具體主題的內部狀態改變時,給所有登記過的觀察者發出通知。具體主題角色又叫做具體被觀察者角色。

  • 抽象觀察者角色

為所有的具體觀察者定義一個接口,在得到主題的通知時更新自己,這個接口叫做更新接口。

  • 具體觀察者角色

具體觀察者角色實現抽象觀察者角色所要求的更新接口,以便使本身的狀態與主題的狀態協調同步。如果需要,具體觀察者角色可以保持一個指向具體主題對象的引用。

3、源代碼實現

  • 基于消息推送模式

主題對象向觀察者推送主題的消息,不管觀察者是否需要。

/*** 觀察者設計模式*/ public class C01_Observer {public static void main(String[] args) {// 創建主題對象ConcreteSubject subject = new ConcreteSubject();// 創建觀察者對象Observer observer1 = new ConcreteObserver("觀察者A");Observer observer2 = new ConcreteObserver("觀察者B");// 注冊觀察者subject.attach(observer1);subject.attach(observer2);// 修改主題狀態subject.change("New State !");/*** 主題狀態:New State !*【觀察者A】狀態:New State !*【觀察者B】狀態:New State !*/} } // 抽象主題角色 abstract class Subject {// 保存注冊的觀察者對象private List<Observer> list = new ArrayList<>();/*** 注冊觀察者對象*/public void attach (Observer observer){list.add(observer);System.out.println("注冊一個觀察者:"+observer.getClass().getName());}/*** 刪除觀察者對象*/public void delete (Observer observer){list.remove(observer);System.out.println("刪除一個觀察者:"+observer);}/*** 通知所有注冊的觀察者對象*/public void notifyObserver (String newState){for (Observer observer : list) {observer.update(newState);}} } // 具體主題角色 class ConcreteSubject extends Subject{private String state ;public String getState (){return state ;}public void change (String newState){state = newState;System.out.println("主題狀態:"+state);//狀態發生改變,通知各個觀察者this.notifyObserver(state);} } // 抽象觀察者角色 interface Observer {/*** 更新接口*/void update (String state); } // 具體觀察者角色 class ConcreteObserver implements Observer{private String name ;// 觀察者狀態private String observerState ;public ConcreteObserver (String name){this.name = name ;}/*** 更新觀察者的狀態,使其與目標的狀態保持一致*/@Overridepublic void update(String state) {observerState = state ;System.out.println("【"+this.name+"】狀態:"+observerState);} }
  • 基于消息拉取模式

主題對象在通知觀察者的時候,傳遞少量信息。如果觀察者需要該消息內容,由觀察者主動到主題對象中獲取,相當于是觀察者從主題對象中拉數據。

該案例基于上述案例修改,觀察者獲取主題對象的消息話題,只有自己感興趣的話題,才進一步獲取內容。

public class C02_Observer_Pull {public static void main(String[] args) {// 創建主題對象ConcreteSubject1 subject = new ConcreteSubject1();// 創建觀察者對象Observer1 observer1 = new ConcreteObserver1("觀察者A","JAVA");Observer1 observer2 = new ConcreteObserver1("觀察者B","MySQL");// 注冊觀察者subject.attach(observer1);subject.attach(observer2);/** 修改主題狀態* 主題狀態:JAVA State !* 【觀察者A】狀態:JAVA State !* 主題狀態:MySQL State !* 【觀察者B】狀態:MySQL State !*/subject.change("JAVA State !","JAVA");subject.change("MySQL State !","MySQL");} } abstract class Subject1 {// 保存注冊的觀察者對象private List<Observer1> list = new ArrayList<>();/*** 注冊觀察者對象*/public void attach (Observer1 observer){list.add(observer);}/*** 刪除觀察者對象*/public void delete (Observer1 observer){list.remove(observer);System.out.println("刪除一個觀察者:"+observer);}/*** 通知所有注冊的觀察者對象,傳入消息的話題*/public void notifyObservers (String msgTopic){for (Observer1 observer : list){observer.update(this);}} } class ConcreteSubject1 extends Subject1 {private String state ;private String msgTopic ;public String getState (){return state ;}public String getMsgTopic (){return msgTopic ;}public void change (String newState,String newMsgTopic){this.state = newState ;this.msgTopic = newMsgTopic ;System.out.println("主題狀態:"+state);this.notifyObservers(msgTopic);} }interface Observer1 {/*** 更新接口* @param subject 傳入主題對象,方面獲取相應的主題對象的狀態*/void update(Subject1 subject); } class ConcreteObserver1 implements Observer1{private String name ;// 選擇話題private String msgTopic ;// 觀察者狀態private String observerState ;public ConcreteObserver1 (String name,String msgTopic){this.name = name ;this.msgTopic = msgTopic ;}@Overridepublic void update(Subject1 subject) {ConcreteSubject1 concreteSubject1 = (ConcreteSubject1)subject ;// 只有指定話題才拉取消息if (concreteSubject1.getMsgTopic().equals(msgTopic)){observerState = concreteSubject1.getState();System.out.println("【"+this.name+"】狀態:"+observerState);}} }

4、兩種模式比較

推模式是假定主題對象知道觀察者需要的數據,直接推送,使得觀察者對象難以復用;而拉模式是主題對象不知道觀察者具體需要什么數據,將把自身傳遞給觀察者,按需要取值。

二、JDK中應用

JAVA語言的java.utill類庫里面,提供了一個Observable類以及一個Observer接口,構成JAVA語言對觀察者模式的支持。

1、Observer接口

這個接口只定義了一個方法,即update()方法,當被觀察者對象的狀態發生變化時,被觀察者對象的notifyObservers()方法就會調用這一方法。

package java.util; /*** A class can implement the <code>Observer</code> interface when it* wants to be informed of changes in observable objects. */ public interface Observer {/*** This method is called whenever the observed object is changed. An* application calls an <tt>Observable</tt> object's*/void update(Observable o, Object arg); }

2、Observable類

被觀察者類都是java.util.Observable類的子類。java.util.Observable提供方法支持觀察者對象。

  • setChanged方法:觀察者對象的狀態發生了變化。
  • notifyObservers:調用所有登記過的觀察者對象的update()方法。
package java.util; public class Observable {private boolean changed = false;private Vector obs;/** Construct an Observable with zero Observers. */public Observable() {obs = new Vector();}/**將一個觀察者添加到觀察者聚集上面*/public synchronized void addObserver(Observer o) {if (o == null)throw new NullPointerException();if (!obs.contains(o)) {obs.addElement(o);}}/** 將一個觀察者從觀察者聚集上刪除 */public synchronized void deleteObserver(Observer o) {obs.removeElement(o);}public void notifyObservers() {notifyObservers(null);}/*** 如果本對象有變化(那時hasChanged 方法會返回true)* 調用本方法通知所有登記的觀察者,即調用它們的update()方法* 傳入this和arg作為參數*/ public void notifyObservers(Object arg) {Object[] arrLocal;synchronized (this) { if (!changed)return;arrLocal = obs.toArray();clearChanged();}for (int i = arrLocal.length-1; i>=0; i--)((Observer)arrLocal[i]).update(this, arg);}/** 將觀察者聚集清空 */public synchronized void deleteObservers() {obs.removeAllElements();}/** 將“已變化”設置為true */protected synchronized void setChanged() {changed = true;}/** 將“已變化”重置為false */protected synchronized void clearChanged() {changed = false;}public synchronized boolean hasChanged() {return changed;}public synchronized int countObservers() {return obs.size();} }

3、應用案例

public class C03_Observer_JDK {public static void main(String[] args) {//創建被觀察者對象MsgSource msgSource = new MsgSource();//創建觀察者對象,并將被觀察者對象登記MsgConsumer watcher = new MsgConsumer(msgSource);msgSource.setData("Hello,Java");msgSource.setData("Bye Java");} } class MsgSource extends Observable {private String data = "";public String getData() {return data;}public void setData(String data) {if(!this.data.equals(data)){this.data = data;setChanged();}notifyObservers();} } class MsgConsumer implements java.util.Observer {// 添加觀察者public MsgConsumer(Observable msgSource){msgSource.addObserver(this);}// 狀態獲取@Overridepublic void update(Observable o, Object arg) {System.out.println("消息內容:" + ((MsgSource)o).getData());} }

三、優缺點總結

觀察者模式的主要的作用是對象解耦,將觀察者和被觀察者隔離。

程序中包括多個被觀察者和多個被觀察者,開發和調試比較復雜,而且Java中的消息的通知默認是順序執行的,一個觀察者的執行阻塞會影響整體的執行效率。

四、源代碼地址

GitHub·地址 https://github.com/cicadasmile/model-arithmetic-parent GitEE·地址 https://gitee.com/cicadasmile/model-arithmetic-parent

總結

以上是生活随笔為你收集整理的Java描述设计模式(11):观察者模式的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 在线观看免费www | 一卡二卡三卡在线视频 | 日韩精品免费一区二区在线观看 | 男女超爽视频免费播放 | 在线免费观看av不卡 | aaa黄色| 一区二区三区亚洲视频 | 超碰1000| 高h视频在线播放 | 狼人综合伊人 | 在线成人欧美 | 日韩欧美一二区 | 欧美精品一区三区 | 国产又色又爽又黄又免费 | 中文字幕二区在线观看 | 欧美性天天影院 | 国产一二三 | 少妇一级淫片日本 | 黄色中文字幕在线观看 | 日本性高潮视频 | av福利在线看 | 中文字幕爱爱 | 国产精品国产三级国产aⅴ 欧美bbbbbbbbbbbb18av | 国产a国产片 | 久久久久久久久久久丰满 | 波多野结衣在线一区二区 | 污污视频在线看 | 五月天中文字幕在线 | 日日狠狠久久偷偷四色综合免费 | 亚洲精品高清在线 | 免费成人在线观看动漫 | 狠狠艹视频 | 亚洲天堂伊人 | 无码一区二区三区在线 | 波多野结衣绝顶大高潮 | 中出少妇| 秋霞午夜影院 | 日韩无码精品一区二区 | 成人av手机在线观看 | 亚洲欧美一区二区三区四区 | 美女18毛片 | 久久怡春院 | 国产孕妇一区二区三区 | 亚洲综合成人亚洲 | 女女h百合无遮涩涩漫画软件 | 黄色靠逼视频 | 午夜激情福利在线 | 色亭亭 | 精品在线一区二区三区 | 欧美亚洲 | 精品久久久免费 | 福利视频在线免费观看 | 日韩成人av毛片 | 亚洲伦理视频 | 亚洲AV无码乱码国产精品牛牛 | 久久国产加勒比精品无码 | 免费看的一级片 | 亚洲小说图片区 | 日韩人妻一区二区三区 | 无遮挡在线观看 | 最新av中文字幕 | 30一40一50女人毛片 | 欧美久操 | 肉丝美足丝袜一区二区三区四 | 日本大乳美女 | 精品国产va久久久久久久 | 国产理论av | 亚洲v欧美v另类v综合v日韩v | 亚洲激情片| 致命弯道8在线观看免费高清完整 | 国产九九九| 成人在线视频网站 | 人人爱人人搞 | 亚洲中文字幕无码一区二区三区 | 就爱操av| 亚洲天堂中文在线 | 欧美日韩国产二区 | 精品久久久久久久久久久久久久久久 | 亚洲欧美另类综合 | 成人av18| 精品久久久久久久免费人妻 | 国产精品啪 | 青青操视频在线观看 | 久久久久亚洲色欲AV无码网站 | 高清av在线 | 中文无码日韩欧 | 日韩夜色| 久久重口味 | 午夜精品福利一区二区 | 亚洲av无码精品色午夜 | 久久久久久国产免费a片 | 无码精品视频一区二区三区 | 免费看av在线 | 欧美在线你懂的 | 亚洲欧洲一区二区 | 一边摸内裤一边吻胸 | 四虎www| 亚洲福利电影网 | 欧美成人三级伦在线观看 |