1.定义

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。

2.解决问题

——订阅报纸

看起来订阅者是直接根有据打交道,但实际上,订阅者的订阅数据是被邮寄传递到报社,当报社出了报纸,报社按订阅信息交给邮局,邮局在代为发送到订阅者手里。在整个过程中,邮局起到一个中转的作用。

使用观察者模式来解决问题public class Subject {

private List readers = new ArrayList();

public void attach(Observer reader) {

readers.add(reader);

}

public void detach(Observer observer) {

readers.remove(observer);

}

protected void notifyObservers() {

for (Observer reader : readers)

reader.update(this);

}

}

public class NewsPaper extends Subject {

private String content;

public String getContent() {

return content;

}

public void setContent(String content) {

this.content = content;

super.notifyObservers();

}

}

public interface Observer {

public void update(Subject subject);

}

public class Reader implements Observer {

private String name;

public void update(Subject subject) {

name = ((NewsPaper)subject).getContent();

System.out.println(name);

}

}

public class Client {

public static void main(String[] args) {

// 创建一个报纸,作为目标

NewsPaper subject = new NewsPaper();

// 创建一个读者

Reader reader1 = new Reader();

Reader reader2 = new Reader();

// 注册订阅者

subject.attach(reader1);

subject.attach(reader2);

// 要出报纸啦

subject.setContent("New");

}

}

3.模式讲解

上述问题中订阅者最关心的问题时是何时能收到最新处的报纸,但要是报纸出版的时间不固定怎么办?进一步抽象这个问题:当一个对象的状态发生改变的时候,如果让依赖于它的所有对象得到通知,并进行相应的处理呢?

解决思路

这是一个典型一对多的对象关系,一个报纸对象,有很多个订阅者对象来订阅,当报纸出版的时候,也就是报纸对象改变的时候。观察者模式处理这种问题时,把这多个订阅者称为观察者:Observer,多个观察者观察的对象称为目标:Subject。

一个目标可以有任意多个观察者独享,一旦目标的状态发生改变,所有注册的观察者都会得到通知,然后各个观察者会对通知做出相应的响应,执行相应的业务功能处理,并使自己的状态与目标状态保持一致。

示例代码public class Subject {

// 用来保存注册的观察者对象

private List observers = new ArrayList();

// 注册观察者对象

public void attach(Observer observer) {

observers.add(observer);

}

// 删除观察者对象

public void detach(Observer observer) {

observers.remove(observer);

}

// 通知所有注册的观察者对象

protected void notifyObservers() {

for (Observer observer : observers)

observer.update(this);

}

}

public class ConcreteSubject extends Subject {

private String subjectState;

public String getSubjectState() {

return subjectState;

}

public void setSubjectState(String subjectState) {

this.subjectState = subjectState;

// 状态改变了,通知各个观察者

this.notifyObservers();

}

}

public interface Observer {

public void update(Subject subject);

}

public class ConcreteObserver implements Observer {

private String observerState;

public void update(Subject subject) {

// 可能需要更新观察者状态,使其与目标的状态保持一致

observerState = ((ConcreteSubject) subject).getSubjectState();

}

}

应用范围

按照模式的定义,目标和观察者之间是典型的一对多关系。但如果观察者只有一个,也是可以的;同样,一个观察者也可以观察多个目标。

单向依赖

在观察者模式中,观察者和目标是单向依赖,只有观察者依赖于目标,而目标不能依赖与观察者。

观察者模式调用顺序示意图

在使用观察者模式时,分为两个阶段:

第一个阶段是准备阶段,即维护目标和观察者关系的阶段;

第二阶段是实际运行阶段。

推模式和拉模式

推模式:目标对象主动向观察者推送目标的详细信息,不管观察者是否需要,推送的信息通常是目标对象的全部或部分数据,相当于广播通信。

拉模式:目标对象在通知观察者的时候,只传递少量信息,如果观擦或者需要更具体的信息,由观察者主动到目标对象中获取,相当于观察者从目标对象中拉数据。

Java观察者模式

java.util包里有一个Observable类,还有一个接口Observer,其中定义了update方法,就是观察者接口。public class NewsPaper extends java.util.Observable {

private String content;

public String getContent() {

return content;

}

public void setContent(String content) {

this.content = content;

// 注意在Java中Observer模式的时候,下边这句不可少

this.setChanged();

// 然后主动通知,这里用的推模式

this.notifyObservers(this.content);

}

}

public class Reader implements java.util.Observer {

private String name;

public void update(Observable o, Object obj) {

// 这是采用推的方式

System.out.println(name + obj);

// 这是采用拉的方式

System.out.println(name + ((NewsPaper) o).getContent());

}

}

public class Client {

public static void main(String[] args) {

// 创建一个报纸,作为目标

NewsPaper subject = new NewsPaper();

// 创建一个读者

Reader reader1 = new Reader();

Reader reader2 = new Reader();

// 注册订阅者

subject.addObserver(reader1);

subject.addObserver(reader2);

// 要出报纸啦

subject.setContent("New");

}

}

适配器模式的优缺点:

优点:实现了观察者和目标之间的抽象耦合,实现了动态联动,支持广播通信

缺点:可能会引起无谓的操作

4.思考

观察者模式的本质是:触发联动

当修改目标对象的状态时,就会触发相应的通知,然后会循环调用所有注册的观擦或者对象的相应方法,其实就相当于联动调用这些观察者的方法。

何时选用适配器模式

当一个抽象模型有两个方面,其中一个方面的操作依赖于另一个方面的状态变化,可以选用观察者模式;

如果在更改一个对象的时候,需要同时连带改变其他的喜爱那个,而且不知道究竟应该有多少对象需要被连带改变,可以选用观察者模模式;

当一个对象必须通知其他对象,但是有希望这个对象和其他被通知的对象是松散耦合的,即这个对象其实不想知道具体被通知的对象,可以选用观察者模式。

说明:笔记内容摘自《研磨设计模式》陈臣,王斌

java观察者模式本质_6.[研磨设计模式笔记]观察者模式相关推荐

  1. JAVA架构之路(设计模式之观察者模式)

    设计模式之观察者模式 定义:对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新 核心原理: 1.被观察者中维护一个观察者对象列表 2.观察者可新增可可移 ...

  2. java 分时图_软件设计模式(观察者模式)——模拟股票价格变动并绘制分时图和K线图...

    一.观察者模式简介: 首先看百度百科上对观察者模式的简介:观察者模式(Observer)完美的将观察者和被观察的对象分离开.举个例子,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数 ...

  3. php观察者模式使用场景,php设计模式系列--观察者模式

    模式定义 观察者模式(observer pattern): 定义对象间的一种一对多(或一对一)的依赖关系,当被观察者状态发生改变时,注册的观察者都会被通知. 观察者模式又称 发布-订阅(publish ...

  4. 4.[研磨设计模式笔记]适配器模式

    1.定义 将一个类的接口转换成客户希望的另外一个接口.适配器模式使得原本由于接口不兼容而不能一起工作的哪些类可以一起工作. 2.解决问题 --日志管理 不用模式的解决方案 版本一:用户要求日志以文件的 ...

  5. java 观察者模式_图解Java设计模式之观察者模式

    图解Java设计模式之观察者模式 天气预报项目需求 天气预报设计方案 1 - 普通方案 观察者模式(Observer)原理 观察者模式解决天气预报需求 观察者模式在JDK应用的源码分析 天气预报项目需 ...

  6. java设计模式观察者模式吗_Java设计模式之观察者模式原理与用法详解

    Java设计模式之观察者模式原理与用法详解 本文实例讲述了Java设计模式之观察者模式原理与用法.分享给大家供大家参考,具体如下: 什么是观察者模式 可以这么理解: 观察者模式定义了一种一对多的依赖关 ...

  7. Java设计模式系列--观察者模式(使用)

    原文网址:Java设计模式系列--观察者模式(使用)_IT利刃出鞘的博客-CSDN博客 简介 说明 本文用示例介绍观察者模式的用法. 观察者模式的含义 以微信公众号为例.我们关注了某个微信公众号后能收 ...

  8. Java设计模式之观察者模式(UML类图分析+代码详解)

    大家好,我是一名在算法之路上不断前进的小小程序猿!体会算法之美,领悟算法的智慧~ 希望各位博友走过路过可以给我点个免费的赞,你们的支持是我不断前进的动力!! 加油吧!未来可期!! 本文将介绍java设 ...

  9. java中线程观察者模式_设计模式之--观察者模式

    在日常生活中,有很多需要我们关注的事务(比如,股市,楼市等),这些事务我们可以称之为主题或者叫信息发布者,观察主题的目的是想了解主题的变化(消息).一种方法当然是采用盯人策略,但这种方法有个固有的缺点 ...

最新文章

  1. 单林多域群集环境中将Exchange 2003迁移到Exchange 2010系列之五
  2. Nginx入门笔记之————配置文件结构
  3. 页面加载完毕_【前端面试】dom 的解析,加载,渲染
  4. python获取当前窗口句柄_人生苦短,我学python之python+selenium 多窗口、句柄(handle)...
  5. docker network
  6. Qt::WA_NoMousePropagation用法
  7. java bitset用途_BitSet的用法
  8. linux shell跳板机,用shell开发跳板机
  9. Substitute Algorithm(替换算法)
  10. 如何更换里讯浏览器的皮肤?里讯浏览器更换皮肤的方法
  11. 教你如何使用FusionInsight SqoopShell
  12. 网络连接数4000多正常吗_怀孕36周时胎儿发育情况是怎样的?胎儿体重有4斤多正常吗?...
  13. [转载] python 去除字符串的标点符号 用_Python成为专业人士笔记–String字符串方法
  14. 【转】android开发必看资源URL
  15. C 语言调用python 脚本函数
  16. 一篇Word论文的字体格式是什么?
  17. wx2540h配置教程_H3C WX2540H系列无线控制器 安装指导-6W101
  18. 高通量DNA测序数据的生物信息学方法
  19. 了解git裸仓库并利用post-receive自动化部署
  20. 项目管理知识体系指南 (一)

热门文章

  1. Linux基础入门(一)
  2. eclipse中下载spring-tool-suite插件遇到的问题
  3. laravel log 对象_swoole运行模式加速laravel应用的详细介绍(life)
  4. docker如何部署python项目_Docker如何部署Python项目的实现详解
  5. python复制之坑
  6. OpenCV与图像处理学习二——图像直方图与色彩空间
  7. 【每日SQL打卡】​​​​​​​​​​​​​​​DAY 8丨平面上的最近距离【难度中等】
  8. 一篇文章搞懂数据仓库:三范式与反范式
  9. CompletableFuture详解~supplyAsync
  10. Spring Data JPA 从入门到精通~实际工作的应用场景