设计模式九: 观察者模式(Observer Pattern)
简介
观察者属于行为型模式的一种, 又叫发布-订阅模式. 如果一个对象的状态发生改变,依赖他的对象都将发生变化, 那么这种情况就适合使用观察者模式.
它包含两个术语,主题(Subject),观察者(Observer), 主题管理一个观察者的列表, 并在状态发生变化时通知到他们.
实现层面上, 主题定义了一个观察者列表并可以管理这个列表(将观察者注册进去和撤销注册的行为), 同时定义了通知到所有观察者的行为.
Java类库有默认的观察者实现类Observer. 使用观察者模式的还有事件监听, RxJava等.
意图
定义对象之间的一对多依赖,当一个对象状态改变时,它的所有依赖都会收到通知并且自动更新状态。
类图

实现
一. 定义抽象观察者
/**
* 观察者抽象角色
*/
public interface MyObserver {
void update(Subject subject);
}
二. 定义抽象主题
/**
* 主题抽象角色
*/
public abstract class Subject {
private ArrayList<MyObserver> list = new ArrayList<MyObserver>();
public Subject register(MyObserver observer){
if(!list.contains(observer)){
list.add(observer);
}
return this;
}
public Subject unRegister(MyObserver observer){
if(list.contains(observer)){
list.remove(observer);
}
return this;
}
public final void notifyObservers(){
for (MyObserver item:list) {
item.update(this);
}
}
/**
* 具体状态的变更
*/
abstract void change();
}
三. 定义具体主题
/**
* 具体主题角色
*/
@Data
public class ConcreteSubject extends Subject {
private String name;
public void change() {
this.setName("王多鱼");
super.notifyObservers();
}
}
四. 定义观察者的实现, 分别定义两个不同实现
public class UncleObserver implements MyObserver {
public void update(Subject subject) {
ConcreteSubject concreteSubject = (ConcreteSubject)subject;
System.out.println("UncleObserver 知道了: "+concreteSubject.getName());
}
}
public class HentaiObserver implements MyObserver {
public void update(Subject subject) {
ConcreteSubject concreteSubject = (ConcreteSubject)subject;
System.out.println("HentaiObserver 知道了: "+concreteSubject.getName());
}
}
五. 调用, 首先注册观察者,然后调用主题的变更方法
// 实例化主题后为其注册了两个观察者的实例, 并最终调用主题的变更方法触发通知行为
public static void main(String[] args) {
new ConcreteSubject()
.register(new UncleObserver())
.register(new HentaiObserver())
.change();
}
总结
关键点: 定义通知到观察者的方法要注意, 如果有耗时严重的会阻塞其他观察者得到通知, 可以异步多线程实现; 避免循环引用;
观察者分推模式和拉模式, 推模式是指将主题的变更信息发送给观察者, 观察者可以用, 也可以不用. 拉模式则是将主题的引用发送给观察者, 观察者通过引用根据自己需要获取所需信息. 示例中使用的就是这种模式.
代码修改为推模式
// 观察者的方法接收具体信息
void update(String name);
// 主题的通知方法做相应修改
public final void notifyObservers(){
for (MyObserver item:list) {
item.update("王多鱼");
}
}
设计模式九: 观察者模式(Observer Pattern)的更多相关文章
- 乐在其中设计模式(C#) - 观察者模式(Observer Pattern)
原文:乐在其中设计模式(C#) - 观察者模式(Observer Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 观察者模式(Observer Pattern) 作者:weba ...
- 二十四种设计模式:观察者模式(Observer Pattern)
观察者模式(Observer Pattern) 介绍定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新. 示例有一个Message实体类,某些对象 ...
- [设计模式] 19 观察者模式 Observer Pattern
在GOF的<设计模式:可复用面向对象软件的基础>一书中对观察者模式是这样说的:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新.当一个 ...
- c#设计模式之观察者模式(Observer Pattern)
场景出发 一个月高风黑的晚上,突然传来了尖锐的猫叫,宁静被彻底打破,狗开始吠了,大人醒了,婴儿哭了,小偷跑了 这个过程,如果用面向对象语言来描述,简单莫过于下: public class Cat { ...
- 设计模式之观察者模式(Observer pattern)
最近参加了一次面试,其中笔试题有一道编程题,在更换掉试题的描述场景后,大意如下: 上课铃声响起,学生A/B/C/D进入教室:下课铃声响起,学生A/B/C/D离开教室. 要求使用设计模式的思想完成铃与学 ...
- 【设计模式】观察者模式 Observer Pattern
定义:观察者模式定义了对象之间的一对多依赖.当“主题”(Object)状态改变事,所有依赖它的“观察者”(Observer)都会受到通知并自动更新.主题支持观察者订阅和退订. 观察者模式提供了一种对象 ...
- 【UE4 设计模式】观察者模式 Observer Pattern
概述 描述 定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新.观察者模式又叫做 发布-订阅(Publish/Subscribe)模式 模型-视图(M ...
- 设计模式-观察者模式(Observer Pattern)
观察者模式(Observer Pattern):定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己. 观察者 ...
- 设计模式 - 观察者模式(Observer Pattern) 详细说明
观察者模式(Observer Pattern) 详细说明 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权全部 ...
随机推荐
- Netstat 常用命令--备忘录
Netstat 用于显示与IP .TCP .UDP 和ICMP 协议相关的统计数据,一般用于检验本机各端口的网络连接情况. 常用参数 -a (all)显示所有选项,默认不显示LISTEN相关-t (t ...
- Oracle的RowId和Rownum
本文参照来自:https://www.cnblogs.com/whut-helin/p/8024860.html 由sql select p.*,rowid,rownum from promotion ...
- cumprod、prod函数
1.prod函数 prod函数用于求矩阵元素的积,其调用格式如下. (1)B=prod(A):若A为向量,则返回所有元素的积:若A为矩阵,则返回各列所有元素的积. (2)B=prod(A,dim):返 ...
- Python脱产8期 Day13 2019/4/28
一 函数的嵌套定义 1在一个函数的内部定义另一个函数. 2.为什么有函数的嵌套定义: # 1)函数fn2想直接使用fn1函数的局部变量,可以讲fn2直接定义到fn1的内部,这样fn2就可以直接访问fn ...
- ansible 与 Jinja2的结合
1.文件架构 [root@master template]# tree . ├── jinj2_test.yml ├── meta ├── tasks ├── templates │ └── te ...
- 《Java2 实用教程(第五版)》教学进程
目录 <Java2 实用教程(第五版)>教学进程 预备作业1:你期望的师生关系是什么? 预备作业2 :学习基础和C语言基础调查 预备作业3:Linux安装及命令入门 第一周作业 第二周作业 ...
- Mysql_安装
安装环境:win7 1.下载zip安装包: MySQL8.0 For Windows zip包下载地址:https://dev.mysql.com/downloads/file/?id=476233, ...
- Ansible第一章:基础认识--小白博客
ansible Ansible:Ansible的核心程序Host Lnventory:记录了每一个由Ansible管理的主机信息,信息包括ssh端口,root帐号密码,ip地址等等.可以通过file来 ...
- JQ面向对象的放大镜
index.html <!DOCTYPE html><html> <head> <meta charset="utf-8" /> & ...
- 解决mysql中文乱码问题 在url后面添加?characterEncoding=utf8