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的小型应用里面,也可以使用中介者模式,比如,把一个界面所有的事件用一个对象来处理,把一个组件触发事件以后,需要操作其他组件的动作都封装到一起,这个对象就是典型的中介者。

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0

观察者模式(Observer)---行为型的更多相关文章

  1. 观察者模式 Observer 发布订阅模式 源 监听 行为型 设计模式(二十三)

    观察者模式 Observer 意图 定义对象一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖他的对象都得到通知并自动更新. 别名:依赖(Dependents),发布订阅(Publish-Su ...

  2. 设计模式 ( 十六 ) 观察者模式Observer(对象行为型)

    设计模式 ( 十六 ) 观察者模式Observer(对象行为型) 1.概述 一些面向对象的编程方式,提供了一种构建对象间复杂网络互连的能力.当对象们连接在一起时,它们就可以相互提供服务和信息. 通常来 ...

  3. 设计模式18:Observer 观察者模式(行为型模式)

    Observer 观察者模式(行为型模式) 动机(Motivation) 在软件构建过程中,我们需要为某些对象建立一种“通知依赖关系”——一个对象(目标对象)的状态发生改变,所有依赖对象(观察者对象) ...

  4. 设计模式 笔记 观察者模式 Observer

    //---------------------------15/04/27---------------------------- //Observer 观察者模式----对象行为型模式 /* 1:意 ...

  5. 设计模式 - 观察者模式(Observer Pattern) 详细说明

    观察者模式(Observer Pattern) 详细说明 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权全部 ...

  6. 乐在其中设计模式(C#) - 观察者模式(Observer Pattern)

    原文:乐在其中设计模式(C#) - 观察者模式(Observer Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 观察者模式(Observer Pattern) 作者:weba ...

  7. 设计模式 - 观察者模式(Observer Pattern) 详细解释

    观察者模式(Observer Pattern) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权全部 ...

  8. java设计模式--观察者模式(Observer)

    java设计模式--观察者模式(Observer) java设计模式--观察者模式(Observer) 观察者模式的定义: 定义对象间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖于它的 ...

  9. 8.5 GOF设计模式四: 观察者模式Observer

    GOF设计模式四: 观察者模式Observer  现实中遇到的问题  当有许多不同的客户都对同一数据源感兴趣,对相同的数据有不同的处理方式,该如 何解决?5.1 定义: 观察者模式  观察者模式 ...

  10. 设计模式-观察者模式(Observer Pattern)

    观察者模式(Observer Pattern):定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己. 观察者 ...

随机推荐

  1. 【AtCoder】ARC068

    ARC 068 C - X: Yet Another Die Game 显然最多的就是一次6一次5 最后剩下的可能需要多用一次6或者6和5都用上 #include <bits/stdc++.h& ...

  2. dede时间标签

    dedecms首页时间标签:1.12-27 样式([field:pubdate function='strftime("%m-%d",@me)'/]) 2.May 15, 2009 ...

  3. golang数据类型

    整数类型   Golang各整数类型分:有符号和无符号,int uint 的大小和系统有关. Golang查看一个变量的数据类型: package main import "fmt" ...

  4. Vim 添加vimgdb支持

    ./configure --enable-gdb --prefix=/usr --enable-multibyte --enable-fontset --enable-xim --enable-gui ...

  5. 【温故知新】php 魔术方法

    <?php class Magic{ private $name; /** *构造方法,在类被实例化时自动调用,一般用于初始化操作 */ public function __construct( ...

  6. poi的基本导入

    一.获取列的值 private String getCell(Cell cell){ if(null == cell){ return ""; } try{ cell.setCel ...

  7. ONNX预训练模型加载

    tvm官网中,对从ONNX预训练模型中加载模型的教程说明 教程来自于:https://docs.tvm.ai/tutorials/frontend/from_onnx.html#sphx-glr-tu ...

  8. Spring MVC 全局异常处理&文件上传

    Spring MVC 全局异常处理 使用SimpleMappingExceptionResolver实现异常处理 在welcome-servlet.xml进行如下配置: <bean class= ...

  9. MySQL cmd操作

    1.开启关闭服务 net start mysql net stio mysql 2.登陆 在CMD命令窗口敲入命令 mysql -hlocalhost -uroot -p 后按回车(注意这里的&quo ...

  10. Spark集群任务提交流程----2.1.0源码解析

    Spark的应用程序是通过spark-submit提交到Spark集群上运行的,那么spark-submit到底提交了什么,集群是怎样调度运行的,下面一一详解. 0. spark-submit提交任务 ...