Head First 设计模式--2 观察者模式 解耦
观察者模式定义了对象之间一对多的依赖,这样依赖,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。
假如有这么一个项目,监控每天的天气状况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 观察者模式 解耦的更多相关文章
- 实践GoF的23种设计模式:观察者模式
摘要:当你需要监听某个状态的变更,且在状态变更时通知到监听者,用观察者模式吧. 本文分享自华为云社区<[Go实现]实践GoF的23种设计模式:观察者模式>,作者: 元闰子 . 简介 现在有 ...
- 乐在其中设计模式(C#) - 观察者模式(Observer Pattern)
原文:乐在其中设计模式(C#) - 观察者模式(Observer Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 观察者模式(Observer Pattern) 作者:weba ...
- 设计模式之观察者模式(Observable与Observer)
设计模式之观察者模式(Observable与Observer) 好久没有写博客啦,之前看完了<设计模式之禅>也没有总结一下,现在回忆一下设计模式之观察者模式. 1.什么是观察者模式 简单情 ...
- 8.5 GOF设计模式四: 观察者模式Observer
GOF设计模式四: 观察者模式Observer 现实中遇到的问题 当有许多不同的客户都对同一数据源感兴趣,对相同的数据有不同的处理方式,该如 何解决?5.1 定义: 观察者模式 观察者模式 ...
- php 设计模式之观察者模式(订阅者模式)
php 设计模式之观察者模式 实例 没用设计模式的代码,这样的代码要是把最上面那部分也要符合要求加进来,就要修改代码,不符合宁增不改的原则 介绍 观察者模式定义对象的一对多依赖,这样一来,当一个对象改 ...
- [JS设计模式]:观察者模式(即发布-订阅者模式)(4)
简介 观察者模式又叫发布---订阅模式,它定义了对象间的一种一对多的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时,所有依赖于它的对象都将得到通知. 举一个现实生活中的例子,例如小 ...
- 再起航,我的学习笔记之JavaScript设计模式18(观察者模式)
观察者模式 观察者模式(Observer): 又被称为发布-订阅者模式或消息机制,定义了一种依赖关系,解决了主体对象与观察者之间功能的耦合. 创建一个观察者对象 首先我们创建一个闭包对象,让其在页面加 ...
- Head First设计模式之观察者模式
一.定义 观察者设计模式定义了对象间的一种一对多的依赖关系,以便一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动刷新. 有时被称作发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多 ...
- 设计模式之观察者模式(c++)
Observer 模式应该可以说是应用最多.影响最广的模式之一,因为 Observer 的一个实例 Model/View/Control( MVC) 结构在系统开发架构设计中有着很重要的地位和意义, ...
随机推荐
- HTML其他基本格式说明
1.<!DOCTYPE>说明页面中使用的HTML版本,只是信息声明 2.元信息元素<meta>,通过属性定义文件信息的名称.内容.文档的关键字.作者及描述等..content内 ...
- MySQL 的 utf8_general_ci 和 utf8_unicode_ci 有什么区别,应如何选择?
一般的解说是 utf8_general_ci 速度较快,utf8_unicode_ci 准确性较好 … 但快在那里,又好在什么地方呢? 首先就其准确性说,这世界上有无数种文字,除了通用的英文使用我们较 ...
- linux 服务器对拷命令scp
1.今天在进行linux下服务部署时由于重新部署的繁杂,所以我决定用scp命令在linux线上服务器(A)拷贝一份服务程序到现有的服务器(B)上: 具体的操作命令是:scp -r A_username ...
- centos7 开机画面定制
安装包 yum install plymouth-plugin-script 设置开机启动画面 mkdir /usr/share/plymouth/themes/tup 创建主题目录 cp /root ...
- DevExpress中的ASPxTreeView 递归显示checknodes并获得选中值
aspx代码 <dx:ASPxTreeView ID="ASPxTreeView1" runat="server"> </dx:ASPxTre ...
- 《转》Spring4 Freemarker框架搭建学习
这里原帖地址:http://www.cnblogs.com/porcoGT/p/4537064.html 完整配置springmvc4,最终视图选择的是html,非静态文件. 最近自己配置spring ...
- Web前端开发规范文档
Web前端开发规范文档 规范目的: 使开发流程更加规范化. 通用规范: TAB键用两个空格代替(windos下tab键占四个空格,linux下TAB键占八个空格). CSS样式属性或者JAVASCRI ...
- 12个css高级技巧.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 学生各门课程成绩统计SQL语句大全
学生成绩表(stuscore): 姓名:name 课程:subject 分数:score 学号:stuid 张三 数学 89 1 张三 语文 80 1 张三 英语 70 1 李四 数学 90 2 李四 ...
- Windows下pry安装和配置
Windows下pry安装和配置 pry是一个增强型的交互式命令行工具,比irb强大. 有自动完成功能,自动缩进,有颜色.有更强大的调试功能. pry 安装很简单. 在终端输入: gem instal ...