观察者模式(Observer)---行为型
1 基础知识
定义:定义了对象之间的一对多依赖,让多个观察者对象同时监听某一个主题对象,当主题对象发生变化时,它的所有依赖(观察者)都会收到通知并更新。
本质:触发联动
使用场景:关联行为场景,建立一套触发机制。
(1)当一个抽象模型有两个方面,其中一个方面的操作依赖于另一个方面的状态变化那么就可以选用观察者模式,将这两者封装成观察者和目标对象,当目标对象变化的时候,依赖于它的观察者对象也会发生相应的变化。这样就把抽象模型的这两个方面分离开了,使得它们可以独立地改变和复用。
(2)如果在更改一个对象的时候,需要同时连带改变其他的对象,而且不知道究竟应该有多少对象需要被连带改变,这种情况可以选用观察者模式,被更改的那一个对象很明显就相当于是目标对象,而需要连带修改的多个其他对象,就作为多个观察者对象了
(3)当一个对象必须通知其他的对象,但是你又希望这个对象和其他被它通知的对象是松散耦合的。也就是说这个对象其实不想知道具体被通知的对象。这种情况可以选用观察者模式,这个对象就相当于是目标对象,而被它通知的对象就是观察
者对象了
优点:观察者和被观察者之间建立一个抽象的耦合;支持广播通信。缺点:观察者之间有过多的细节依赖、提高时间消耗及程序复杂度;要避免循环调用。
2 代码示例
使用场景: 观察者查看一个生成数值的对象,并将其结果显示。不过,不同的观察者显示的方式也不同。
Observer接口:
public interface Observer {
public void update(NumberGenerator numberGenerate);
}
生成数值的抽象类:NumberGenerator
public abstract class NumberGenerator {
//保存观察者们
private ArrayList observers = new ArrayList();
//添加观察者
public void addObserver(Observer observer){
observers.add(observer);
}
//删除观察者
public void deleteObserver(Observer observer){
observers.remove(observer);
}
//向observer发送通知
public void notifyObservers(){
Iterator it = observers.iterator();
while (it.hasNext()){
//调用每个观察者的update方法
Observer o = (Observer)it.next();
o.update(this);
}
}
//获取数值
public abstract int getNumber();
//生成数值
public abstract void execute();
}
子类,生成随机数:RandomNumberGenerator
public class RandomNumberGenerator extends NumberGenerator{
//随机数生成器
private Random random = new Random();
//当前数值
private int number;
//产生10个10以内的数字并向观察者发送通知
public void execute(){
for (int i = 0; i < 10; i++) {
number = random.nextInt(10);
//把每次生成的结果通知给观察者
notifyObservers();
}
}
//获取当前数值
public int getNumber() {
return number;
}
}
观察者1:DigitObserver 以数字的形式显示观察得到的数值
public class DigitObserver implements Observer{
public void update(NumberGenerator numberGenerate) {
System.out.println("观察到的数值:"+numberGenerate.getNumber());
}
}
观察者2:GraphObserver 将观察到的数值以***的形式显示出来
public class GraphObserver implements Observer{
public void update(NumberGenerator numberGenerate) {
System.out.println("图像");
int count = numberGenerate.getNumber();
for (int i = 0; i < count; i++) {
System.out.print("*");
}
System.out.println();
}
}
应用层:
public class Test {
public static void main(String[] args) {
NumberGenerator generator = new RandomNumberGenerator();
Observer observer1 = new DigitObserver();
Observer observer2 = new GraphObserver();
//添加观察者
generator.addObserver(observer1);
generator.addObserver(observer2);
generator.execute();
}
}
注:其实Java已经为我们提供了 Observer模式了但是java.util. observer接口和java.util. Observable类并不好用。理由很简单,传递给java.util. Observer接口的 Subject y角色必须是java.util. observable类强(或者它的子类型)的。但Java只能单一继承,也就说如果 Subject 角色已经是某个类的子类了,那么它将无法继承java.util. Observable类。
3 源代码中的使用
4 相关模式
(1)观察者模式和状态模式
观察者模式和状态模式是有相似之处的。观察者模式是当目标状态发生改变时,触发并通知观察者,让观察者去执行相应的操作。而状态模式是根据不同的状态,选择不同的实现,这个实现类的主要功能就是针对状态相应地操作,它不像观察者,观察者本身还有很多其他的功能,接收通知并执行相应处理只是观察者的部分功能。当然观察者模式和状态模式是可以结合使用的。观察者模式的重心在触发联动,但是到底决定哪些观察者会被联动,这时就可以采用状态模式来实现了,也可以采用策略模式来进行选择需要联动的观察者。
(2)观察者模式和中介者模式
观察者模式和中介者模式是可以结合使用的。前面的例子中目标都只是简单地通知一下,然后让各个观察者自己去完成更新就结束了。如果观察者和被观察的目标之间的交互关系很复杂,比如,有一个界面,里面有三个下拉列表组件,分别是选择国家、省份州、具体的城市,很明显这是一个三级联动,当你选择一个国家的时候,省份/州应该相应改变数据,省份/州一改变,具体的城市也需要改变。这种情况下,很明显需要相关的状态都联动准备好了,然后再一次性地通知观察者。也就是界面做更新处理,不会仅国家改变一下,省份和城市还没有改就通知界面更新。这种情况就可以使用中介者模式来封装观察者和目标的关系在使用 Swing的小型应用里面,也可以使用中介者模式,比如,把一个界面所有的事件用一个对象来处理,把一个组件触发事件以后,需要操作其他组件的动作都封装到一起,这个对象就是典型的中介者。
观察者模式(Observer)---行为型的更多相关文章
- 观察者模式 Observer 发布订阅模式 源 监听 行为型 设计模式(二十三)
观察者模式 Observer 意图 定义对象一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖他的对象都得到通知并自动更新. 别名:依赖(Dependents),发布订阅(Publish-Su ...
- 设计模式 ( 十六 ) 观察者模式Observer(对象行为型)
设计模式 ( 十六 ) 观察者模式Observer(对象行为型) 1.概述 一些面向对象的编程方式,提供了一种构建对象间复杂网络互连的能力.当对象们连接在一起时,它们就可以相互提供服务和信息. 通常来 ...
- 设计模式18:Observer 观察者模式(行为型模式)
Observer 观察者模式(行为型模式) 动机(Motivation) 在软件构建过程中,我们需要为某些对象建立一种“通知依赖关系”——一个对象(目标对象)的状态发生改变,所有依赖对象(观察者对象) ...
- 设计模式 笔记 观察者模式 Observer
//---------------------------15/04/27---------------------------- //Observer 观察者模式----对象行为型模式 /* 1:意 ...
- 设计模式 - 观察者模式(Observer Pattern) 详细说明
观察者模式(Observer Pattern) 详细说明 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权全部 ...
- 乐在其中设计模式(C#) - 观察者模式(Observer Pattern)
原文:乐在其中设计模式(C#) - 观察者模式(Observer Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 观察者模式(Observer Pattern) 作者:weba ...
- 设计模式 - 观察者模式(Observer Pattern) 详细解释
观察者模式(Observer Pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权全部 ...
- java设计模式--观察者模式(Observer)
java设计模式--观察者模式(Observer) java设计模式--观察者模式(Observer) 观察者模式的定义: 定义对象间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖于它的 ...
- 8.5 GOF设计模式四: 观察者模式Observer
GOF设计模式四: 观察者模式Observer 现实中遇到的问题 当有许多不同的客户都对同一数据源感兴趣,对相同的数据有不同的处理方式,该如 何解决?5.1 定义: 观察者模式 观察者模式 ...
- 设计模式-观察者模式(Observer Pattern)
观察者模式(Observer Pattern):定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己. 观察者 ...
随机推荐
- 初识RedisCluster集群
为什么需要Redis集群 需要提高更大的并发量 Redis官方提出拥有10万QPS的请求量 如果业务需要Redis拥有100万的QPS 可以通过集群来提升并发量. 需要存储更大的数据量 一般服务器的机 ...
- 【LOJ】#3102. 「JSOI2019」神经网络
LOJ#3102. 「JSOI2019」神经网络 首先我们容易发现就是把树拆成若干条链,然后要求这些链排在一个环上,同一棵树的链不相邻 把树拆成链可以用一个简单(但是需要复杂的分类讨论)的树背包实现 ...
- LC 387. First Unique Character in a String
题目描述 Given a string, find the first non-repeating character in it and return it's index. If it doesn ...
- fiddler笔记:web session窗口介绍
1.web session列表的含义:(从左到右) # fiddler通过session生成的ID. Result 响应状态码. Host 接收请求的服务器的主机名和端口号. URL 请求资源的位置. ...
- linux内核exec过程
简介 本文分析linux内核exec系统调用执行过程中可执行文件的加载过程和栈的设置,内核代码版本为2.6.32 分析 \arch\ia64\kernel\process.c中有sys_exec函数的 ...
- ggpubr进行“paper”组图合并,也许比PS,AI更简单
本文转载自微信公众号 “生信补给站”,https://mp.weixin.qq.com/s/41iKTulTwGcY-dHtqqSnLA 多个图形进行组图展示,可以既展示一个“事情”的多个角度,也可以 ...
- R-corrplot相关性绘图,只有你想不到的
初步接触数据集,探索性分析后,经常需要做一个相关分析,得到各变量间的相关系数以及显著性水平. 本文介绍一下R-corrplot包进行相关可视化展示. 一 数据准备 载入所需的R包,利用公共数据集mtc ...
- hdu 3364 高斯入门。。
扣了一个高斯的介绍 比较全面(来自http://blog.csdn.net/duanxian0621/article/details/7408887) 高斯消元法,是线性代数中的一个算法,可用来求解线 ...
- Git详细操作
Git详细操作 一.本地配置 1公钥钥配置 1.参考帮助文档:https://gitee.com/help/ 仓库管理 =公钥管理 =生成/添加SSH公钥 ssh-keygen -t rsa -C & ...
- 微信小程序data-传参
<view bindtap="change" data-index="{{index}}">哈哈</view> change(event ...