Java設計模式-觀察者模式

  • 什麼是觀察者模式?
  • 觀察者模式的結構
  • 代碼實現
  • 實際案例

什麼是觀察者模式?

首先先來看看一個對於觀察者模式一個經典的描述,出自於阎宏博士的 《JAVA與模式》:

观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

可能單看上面一段話有點抽象,接下來再用更實際的描述理解觀察者模式。

觀察者模式的結構

一個軟件系統中存在各種對象,且常常要求在某一個對象狀態發生變化時,某些其他可能與之關聯的對象要做出相應的改變。觀察者模式就正是為了這樣需求而誕生的設計模式,來看看觀察者模式的架構圖:

觀察者模式涉及的角色如下:

  • 抽象主題角色(Abstract Subject): 抽象主題角色把所有對觀察者對象的引用都保存到 observers:ArrayList 中,每個主題都可以有任意個觀察者。抽象主題提供一個接口,可以增加 attach 或刪除 detach 觀察者對象,因此抽象主題角色又叫做抽象被觀察者(Abstract Observable)角色。

  • 具體主題角色(Concrete Subject): 將有關狀態存入具體觀察者對象,在具體主題的內部狀態發生改變時,給所有登記過觀察者發出通知,因此具體主題角色又叫做具體被觀察者(Concrete Observable)角色。

  • 抽象觀察者角色(Abstract Observer): 為所有具體觀察者提供一個接口,在得到主題的通知時更新自己 update

  • 具體觀察者角色(Concrete Observer): 存儲與主題的狀態自恰的狀態。具體觀察者角色要實現所有抽象觀察者提供的所有接口,以便使自己的狀態跟主題的狀態互相協調。

接下來來看看觀察者模式的原代碼!

代碼實現

package observer;/*
* 抽象觀察者類
* */public abstract class AbstractObserver {// 更新觀察者的狀態public abstract void update(String newState);
}
package observer;/*
* 抽象主題類
* */import java.util.ArrayList;
import java.util.List;public abstract class AbstractSubject {// 觀察者集合List<AbstractObserver> observers = new ArrayList<AbstractObserver>();// 添加觀察者public void add(AbstractObserver observer) {observers.add(observer);}// 移除觀察者public void remove(AbstractObserver observer) {observers.remove(observer);}// 通知所有註冊的觀察者public void notify(String newState) {for(AbstractObserver observer : observers) {observer.update(newState);}}
}
package observer;/** 具體觀察者類* */public class ConcreteObserver extends AbstractObserver {// 觀察者名稱private String name;public ConcreteObserver(String name) {this.name = name;}@Overridepublic void update(String newState) {System.out.println("觀察者 " + this.name + " 狀態被更新為 " + newState);}
}
package observer;/** 具體主題類* */public class ConcreteSubject extends AbstractSubject {private String state;public ConcreteSubject(String state) {this.state = state;}public String getState() {return state;}// 主題狀態發生變化public void change(String newState) {this.state = newState;this.notify(newState);}
}
package observer;/** 測試類* */public class Main {public static void main(String[] args) {ConcreteSubject subject = new ConcreteSubject("initial state");ConcreteObserver observer1 = new ConcreteObserver("observer1");ConcreteObserver observer2 = new ConcreteObserver("observer2");ConcreteObserver observer3 = new ConcreteObserver("observer3");subject.add(observer1);subject.add(observer2);subject.add(observer3);System.out.println("主題角色狀態: " + subject.getState());subject.change("change state");System.out.println("主題角色狀態: " + subject.getState());}
}

測試類運行結果如下:

實際案例

最後通過一個實際案例場景,運用觀察者模式滿足需求。

假設今天要模擬一個學校班級,首先會有老師跟學生。老師會自己知道作業狀態,且會布置作業給學生。而一旦收到老師布置的作業,學生便會開始完成作業。來看看用觀察者模式的代碼實現:

package School;/** 抽象觀察者類* */public abstract class AbstractStudent {// 學生完成作業,相當於更新作業狀態public abstract void finish(String homework);
}
package School;/** 抽象主題類* */import java.util.ArrayList;
import java.util.List;public abstract class AbstractTeacher {// 老師管理的學生集合private List<AbstractStudent> students = new ArrayList<AbstractStudent>();// 增加學生public void add(AbstractStudent student) {students.add(student);}// 移除學生public void remove(AbstractStudent student) {students.remove(student);}// 老師布置作業public void assignHomework(String homework) {for(AbstractStudent student : students) {student.finish(homework);}}
}
package School;/** 具體觀察者類* */public class ConcreteStudent extends AbstractStudent {String name;int number;public ConcreteStudent(String name, int number) {this.name = name;this.number = number;}@Overridepublic void finish(String homework) {System.out.println("學號 " + this.number + " " + this.name + " 同學正在完成作業 " + homework);}
}
package School;/** 具體主題類* */public class ConcreteTeacher extends AbstractTeacher {private String homework = "目前沒有作業";public String getHomework() {return this.homework;}public void notifyStudents(String homework) { // 老師通知學生this.homework = homework;this.assignHomework(homework);}
}
package School;/** 測試類* */public class Main {public static void main(String[] args) {ConcreteTeacher teacher = new ConcreteTeacher();ConcreteStudent student1 = new ConcreteStudent("Tristan", 181250083);ConcreteStudent student2 = new ConcreteStudent("William", 181250168);ConcreteStudent student3 = new ConcreteStudent("cyzPaul", 181250015);ConcreteStudent student4 = new ConcreteStudent("Donovan", 181250003);teacher.add(student1);teacher.add(student2);teacher.add(student3);teacher.add(student4);System.out.println("目前作業狀態 : " + teacher.getHomework());teacher.notifyStudents("homework1");System.out.println("目前作業狀態 : " + teacher.getHomework());}
}

測試類運行結果如下:

Java 設計模式 - 觀察者模式相关推荐

  1. C++設計模式——觀察者模式

    觀察者模式:定義了對象之閒的一對多依賴,這樣一來,儅一個對象改變狀態時,它的所有依賴者都會收到通知並自動更新. 觀察者模式的類圖: 代碼示例 :利用WeatherData對象取得數據,更新concre ...

  2. Java 設計模式 - 適配器模式

    Java 設計模式 - 適配器模式 適配器模式前言 模式概述 模式結構 模式具體應用 類適配器模式 對象適配器模式 優缺點 適配器模式前言 在現實生活中,經常出現兩個對象因接口不兼容而不能在一起工作的 ...

  3. HeadFirst之设计模式 觀察者模式

    觀察者顧名思義,就是一個觀察者,如當我們訂閱報紙,我們就是報紙的觀察者,報紙就是一個主題(Subject),我們可以訂閱報紙可以退訂報紙,而報社的一方只要有訂閱者就得時時刻刻地準備發送報紙.     ...

  4. android觀察者模式三種實現方法

    demo: EditText計算身高體重,使用觀察者模式實現 1.內部類實現 package com.zhg.day0102;import android.app.Activity; import a ...

  5. C#適應練習:幾種常見設計模式的實現

    一.單例及原型模式 單例:即使用一個固定對象的對象進行操作,實現起來很簡單 using System; using System.Collections.Generic; using System.L ...

  6. 設計模式之Visitor

    Visitor定義 作用於某個物件群中各個物件的操作. 它可以使你在不改變這些物件本身的情況下,定義作用於這些物件的新操作. 在Java中,Visitor模式實際上是分離了collection結構中的 ...

  7. 設計模式之王 - MVC

    Model-View-Controller (縮寫 MVC ) 是 Cocoa 框架的一部分,並且毋庸置疑是最常用的設計模式之一.它可以幫你把物件根據職責進行劃分和歸類. 作為劃分依據的三個基本職責是 ...

  8. java设计模式2-观察者模式

    java设计模式2-观察者模式 什么是观察者模式? 何谓观察者模式?观察者模式定义了对象之间的一对多依赖关系,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并且自动更新. 在这里,发生改变 ...

  9. C++設計模式——策略模式

    模式定義:策略模式定義了算法族,分別封裝起來,讓它們之間可以互相替換,此模式讓算法的變化獨立于使用算法的客戶. 舉個例子來説,不同鴨子的行爲是不同的,我們可以把變化的行爲提取出來進行封裝.我將鴨子的飛 ...

最新文章

  1. Matlab进行录制、存储、绘制、读取音频
  2. 绝望的力量:美术创作者的晋级之路
  3. dotNET面试题汇总系列连载(1):基础语法
  4. 程序员的SOHO:接单到完成的全过程
  5. 简述java异常机制处理,简述Java中的异常处理机制
  6. Linux的i2c驱动详解
  7. 华为软挑2019总结
  8. AD09报错解决方法
  9. Eureka服务治理
  10. php 时辰,时辰算命 - 免费在线算命 - 三藏算命
  11. python将doc文件转换docx
  12. IPv6路由(学习日记)
  13. 维特比算法在隐马尔可夫模型中的应用
  14. 学会给视频添加渐入、色彩变幻特效,简单几步骤做创意小视频
  15. Kerbose 原理
  16. 现代黄河三角洲的冲淤分区及地层特征
  17. java动态代理详解及实际应用
  18. HealthKit 框架详细解析
  19. 2018北邮计算机、网研、网安803考研报考建议
  20. Google 的秘密 PageRank彻底解说 中文版

热门文章

  1. (软件构造)2022哈工大软件构造 lab2内容以及心得
  2. springboot在线原型工程生成工具
  3. windows10开启wifi热点
  4. clio7.0测试软件如何安装,原装CLIO10.2 QC电声测试仪
  5. 【DM8分区表的创建和管理】
  6. ZERO助手新版更新[2008408]支持起点新站、新浪读书频道、17K、逐浪、幻剑等小说站点及百度推广...
  7. 逐浪装裱大师APPv0.0.1已上架各大应用市场
  8. 达梦数据库表空间管理实例
  9. 常用视频标准尺寸和码率
  10. mysql怎么对列求和