观察者模式定义了对象之间一对多的依赖,这样依赖,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。

假如有这么一个项目,监控每天的天气状况WeatherData(温度,湿度,气压)。有布告板显示天气的不同内容。天气要实时更新,布告板内容也会随着更新。要求可扩展,将来还有可能有别的布告板,WeatherData还有可能添加新内容。

这么一个需要,我们的第一想法就是WeatherData中有三个属性,对应三个获取方法,有几个布告板那就写几个更新方法,在一个大更新方法中分别调用每个布告板的更新方法。

如果这么一写,如果未来又增加了新的布告板,那么就需要在现有的方法中增加这个新的布告板的更新方法,这么一修改了已经写好的代码,那么之前的测试就需要在重新测试一遍。而且这个更新的方法会越来越大,越来越头疼。而且如果有哪个布告板在运行的过程中不想要了,这没法办到。

看一下观察者模式解决这个问题。

直接看代码:

interface Observer {
public void update(float temp, float humidity, float preasure);
} interface DisplayElement {
public void display();
} class CurrentConditionsDisplay implements Observer, DisplayElement {
float temperature;
float humidity;
Subject weatherData; public CurrentConditionsDisplay(Subject weatherData) {
this.weatherData = weatherData;
weatherData.registerObserver(this);
} @Override
public void display() {
System.out.println("temperature, humidity, pressure is " + temperature + " " + humidity);
} @Override
public void update(float temp, float humidity, float preasure) {
this.temperature = temp;
this.humidity = humidity;
this.temperature = preasure;
}
} interface Subject {
public void registerObserver(Observer observer); public void removeObserver(Observer observer); public void notifyObserver();
} class WeatherData implements Subject {
ArrayList<Observer> observers;
float temperature;
float humidity;
float pressure; public WeatherData() {
this.observers = new ArrayList<>();
} @Override
public void registerObserver(Observer observer) {
this.observers.add(observer);
} @Override
public void removeObserver(Observer observer) {
int i = this.observers.indexOf(observer);
if (i > ) {
this.observers.remove(i);
}
} @Override
public void notifyObserver() {
for (Observer observer : observers) {
observer.update(temperature, humidity, pressure);
}
} public void measurementsChanged() {
notifyObserver();
} public void setMeasurements(float temp, float humidity, float pressure) {
this.temperature = temp;
this.humidity = humidity;
this.pressure = pressure;
measurementsChanged();
}
} public class Test {
public static void main(String[] args) {
WeatherData weatherData = new WeatherData();
CurrentConditionsDisplay display = new CurrentConditionsDisplay(weatherData); weatherData.setMeasurements(, , );
display.display();
}
}

这里存在的一个问题是三个属性最好封装成一个对象,这样在以后新增其他属性时候方便修改。

一对多的关系:利用观察者模式,主题是一个有状态的对象,并且可以修改这些状态。另一方面,观察者也有一自己的状态,但是观察者的状态使用主题的状态来更新或显示。这样主题与观察者就能有一个一对多的关系。这里,主题是真正拥有对象的人,观察者只是主题的依赖者。

观察者模式提供了一种对象设计,让主题和观察者之间松耦合:
关于观察者的一切,主题只知道观察者实现了某个接口(Observer接口),主题并不需要知道观察者的具体类是谁和其他的细节。想要增加观察者,只需要实现这个接口。运行时,随时增加删除,主题并不会受到影响。我们可以独立的复用主题或者观察者的代码(在类里实现这些接口即可),改变主题或观察者的一方并不会影响到另一方,因为二者并非紧耦合。

Head First 设计模式--2 观察者模式 解耦的更多相关文章

  1. 实践GoF的23种设计模式:观察者模式

    摘要:当你需要监听某个状态的变更,且在状态变更时通知到监听者,用观察者模式吧. 本文分享自华为云社区<[Go实现]实践GoF的23种设计模式:观察者模式>,作者: 元闰子 . 简介 现在有 ...

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

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

  3. 设计模式之观察者模式(Observable与Observer)

    设计模式之观察者模式(Observable与Observer) 好久没有写博客啦,之前看完了<设计模式之禅>也没有总结一下,现在回忆一下设计模式之观察者模式. 1.什么是观察者模式 简单情 ...

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

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

  5. php 设计模式之观察者模式(订阅者模式)

    php 设计模式之观察者模式 实例 没用设计模式的代码,这样的代码要是把最上面那部分也要符合要求加进来,就要修改代码,不符合宁增不改的原则 介绍 观察者模式定义对象的一对多依赖,这样一来,当一个对象改 ...

  6. [JS设计模式]:观察者模式(即发布-订阅者模式)(4)

    简介 观察者模式又叫发布---订阅模式,它定义了对象间的一种一对多的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时,所有依赖于它的对象都将得到通知. 举一个现实生活中的例子,例如小 ...

  7. 再起航,我的学习笔记之JavaScript设计模式18(观察者模式)

    观察者模式 观察者模式(Observer): 又被称为发布-订阅者模式或消息机制,定义了一种依赖关系,解决了主体对象与观察者之间功能的耦合. 创建一个观察者对象 首先我们创建一个闭包对象,让其在页面加 ...

  8. Head First设计模式之观察者模式

    一.定义 观察者设计模式定义了对象间的一种一对多的依赖关系,以便一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动刷新. 有时被称作发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多 ...

  9. 设计模式之观察者模式(c++)

    Observer 模式应该可以说是应用最多.影响最广的模式之一,因为 Observer 的一个实例 Model/View/Control( MVC) 结构在系统开发架构设计中有着很重要的地位和意义, ...

随机推荐

  1. nodejs 初入

    nodejs 模块路径 1.内置模块 如果传递给require函数的是NodeJS内置模块名称,不做路径解析,直接返回内部模块的导出对象,例:require('http'). 2. nodejs  支 ...

  2. prototype

  3. Java学习-001-JDK安装配置

    本节主要讲述在 Win7 64bit 系统下安装.配置 JDK8u25,敬请参阅.详细步骤如下: 一.JDK下载 您可到 官方网站 或 我的云盘 下载,对应的JDK8u25的安装程序,下载过程不再赘述 ...

  4. logstash使用操作部分

    1.logstash的概念及特点.概念:logstash是一个数据采集.加工处理以及传输(输出)的工具.特点: - 所有类型的数据集中处理 - 不同模式和格式数据的正常化 - 自定义日志格式的迅速扩展 ...

  5. 事务复制-大批量DEL操作

    同事讨论删除发布表历史记录,导致订阅端数据滞后N小时.后来询问得知,发布表T只保留最近31天的数据,每天由Job删除31天前的数据,每天的删除量约400-500万条.默认情况下,在发布端删除400万条 ...

  6. cocos2dx 3.x(动态改变精灵的背景图片)

    //更换精灵CCSprite的图片有两种方式. //直接通过图片更换 //使用setTexture(CCTexture2D*)函数,可以重新设置精灵类的纹理图片. // auto bg = Sprit ...

  7. JS---------IIFE(Imdiately Invoked Function Expression 立即执行的函数表达式)

    +function($){}(jQuery); 今天看到js代码里面有这个格式的代码,不知道啥意思,就去查了一下,我也是js小白.首先前面的+号,这个不是固定非要写+号,只要写一级运算符都可以.目的是 ...

  8. IOS基础面试题

    最近离职了,找工作,光会做项目,对基础不熟,今天就总结了一点面试题. 废话不多说,上题吧: 1.objective-c中的数字对象都有哪些,简述它们与基本数据类型的区别是什么. 基本类型和C一样,主要 ...

  9. 面试:浅谈tcp/udp

    tcp是一种面向连接的.可靠的.基于字节流的传输层通信协议.是专门为了在不可靠的互联网络上提供一个可靠的端到端字节流而设计的,面向字节流. udp(用户数据报协议)是iso参考模型中一种无连接的传输层 ...

  10. 前端里神奇的BFC 原理剖析

    以前在做自适应两栏布局的时候别人口中听到bfc这个词,于是看了各种关于bfc的文章,发现梦想天空介绍的不错,今天就在他的基础上润色一下. 一.BFC是什么? 在解释 BFC 是什么之前,需要先介绍 B ...