设计模式二之观察者模式(Subject-Observer)
观察者模式定义了一系列对象之间的一对多关系,当一个主题对象改变状态,其他所有的依赖者都会收到通知。
好了,你可能会觉得上面的描述略微复杂,较难理解,那么现在我们将用一个简单的例子去讲解这个模式。
我们先来分析出版和订阅的关系:

出版和订阅的关系:
(1) 一家出版公司,负责每天按时出版报纸
(2) 很多个用户订阅报纸,每天会收到出版社出版的报纸内容,用户可以订阅(注册),也可以取消订阅(注销注册信息)。
(3) 出版社和用户之间的关系是一(出版社)对多(用户)的关系,并且用户依赖出版社出版的报纸,以实现对自身信息数据的刷新。
(4) 我们将出版社看成主题,将用户看成观察者,整个过程就是一个 主题---观察者模式,也就是 Subject--Observer模式。
这就是最简单的观察者模式,简单理解了之后,我们来做一个气象站,需求如下:
(1) 我们需要实现一个气象站
(2) 有一个 WearherData 对象负责追踪 温度,湿度和气压的变化
(3) 有很多种不同类型(WeatherObject)的布告板,用来显示当前的天气状况,布告板必须实时更新
分析以上三个条件,可以知道 WeatherData 和 WeatherObject 存在一对多的关系,并且多个 WeatherObject 依赖 WeatherData 进行数据的刷新。

将整个过程采用观察者模式来进行分析:

接下来,我们用代码实现上面的图:
(1) 3个接口,一个Subject (主题接口), 一个 Observer(观察者接口),一个DisplayElement(布告板接口)
Subject(主题)接口:

Observer(观察者接口):

DisplayElement(布告板)接口:

(2) 实现主题(Subject)接口的WeatherData类:
public class WeatherData implements Subject{
private float tempture;
private float pressure;
private float humity;
List<Observer> observers;
public WeatherData() {
observers = new ArrayList<Observer>();
}
@Override
public void registerObserver(Observer obv) {
// TODO Auto-generated method stub
//注册方法中将需要注册的观察者加到List中
observers.add(obv);
}
@Override
public void removeObserver(Observer obv) {
// TODO Auto-generated method stub
//注销方法中将需要注销的观察者移除
int i = observers.indexOf(obv);
if(i>=0)
{
observers.remove(i);
}
}
@Override
public void NotifyAllObserver() {
// TODO Auto-generated method stub
//通知所有观察者进行数据的刷新
for(int i=0 ;i<observers.size(); i++)
{
//获取到每一个观察者的对象,把该对象的所有属性值改变就行
Observer observer = (Observer)observers.get(i);
observer.update(tempture, humity, pressure);
}
}
public void SetMesurements(float tempture, float humity, float pressure)
{
this.humity = humity;
this.pressure = pressure;
this.tempture = tempture;
MeasurementChanged();
}
private void MeasurementChanged() {
// TODO Auto-generated method stub
NotifyAllObserver();
}
}
(3) 现在就可以任意画自己想要的布告板了:
public class CurrentConditionDisplay implements Observer, DisplayElement {
private float tempture;
private float humidity;
private float pressure;
private Subject WeatherData;
@Override
public void display() {
// TODO Auto-generated method stub
//展示布告板
System.out.println(tempture+""+humidity+""+pressure);
}
@Override
public void update(float temp, float humidity, float pressure) {
// TODO Auto-generated method stub
this.humidity = humidity;
this.tempture = temp;
this.pressure = pressure;
display();
}
public CurrentConditionDisplay(Subject weatherData)
{
//在构造方法中注册观察者
this.WeatherData = weatherData;
WeatherData.registerObserver(this);
}
}
(4) 最后,写一个测试类,测试我们画好的布告板:
public class projectTestClass {
public static void main(String[] args)
{
WeatherData weathData = new WeatherData();
CurrentConditionDisplay ss = new CurrentConditionDisplay(weathData);
weathData.SetMesurements(10, 10, 10);
}
}
这就是整个观察者模式的处理过程。
设计模式二之观察者模式(Subject-Observer)的更多相关文章
- C#设计模式之十七观察者模式(Observer Pattern)【行为型】
一.引言 今天是2017年11月份的最后一天,也就是2017年11月30日,利用今天再写一个模式,争取下个月(也就是12月份)把所有的模式写完,2018年,新的一年写一些新的东西.今天我们开始讲& ...
- C#设计模式系列:观察者模式(Observer)
在软件构建过程中,需要为某些对象建立一种“通知依赖关系”,即一个对象的状态发生改变,所有的依赖对象都需要得到通知. 1.观察者模式简介 1.1>.定义 定义对象间的一种一对多的依赖关系,当一个对 ...
- c#设计模式系列:观察者模式(Observer Pattern)
引言 在现实生活中,处处可见观察者模式,例如,微信中的订阅号,订阅博客和QQ微博中关注好友,这些都属于观察者模式的应用.在这一章将分享我对观察者模式的理解,废话不多说了,直接进入今天的主题. 观察者模 ...
- 设计模式学习之观察者模式(Observer,行为型模式)(7)
1.观察者模式又叫做发布-订阅模式. 2.观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己. 3 ...
- 设计模式 之 《观察者模式 (Observer)》
#ifndef __OBSERVER_MODEL__ #define __OBSERVER_MODEL__ #include <string> #include <iostream& ...
- 设计模式 (二)——观察者模式(Observer,行为型)
1.概述 使用设计模式可以提高代码的可复用性.可扩充性和可维护性.观察者模式(Observer Pattern)属于行为型模式,在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都 ...
- C#设计模式之十六观察者模式(Observer Pattern)【行为型】
一.引言 今天是2017年11月份的最后一天,也就是2017年11月30日,利用今天再写一个模式,争取下个月(也就是12月份)把所有的模式写完,2018年,新的一年写一些新的东西.今天我们开始讲“行为 ...
- C#设计模式(17)——观察者模式(Observer Pattern)
一.引言 在现实生活中,处处可见观察者模式,例如,微信中的订阅号,订阅博客和QQ微博中关注好友,这些都属于观察者模式的应用.在这一章将分享我对观察者模式的理解,废话不多说了,直接进入今天的主题. 二. ...
- 设计模式 ( 十六 ) 观察者模式Observer(对象行为型)
设计模式 ( 十六 ) 观察者模式Observer(对象行为型) 1.概述 一些面向对象的编程方式,提供了一种构建对象间复杂网络互连的能力.当对象们连接在一起时,它们就可以相互提供服务和信息. 通常来 ...
随机推荐
- WEB API系列(一):WEB API的适用场景、第一个实例
在我前一篇博客中已经给各位简单介绍了HTTP协议与RestFul API的关系,以及一些基本的HTTP协议知识,在这些知识的铺垫下,今天,我们一起来讨论一下WEB API的适用场景,然后写我们第一个W ...
- 题解 CF934A 【A Compatible Pair】 ——贪心
题意: 给定两个数列 \(A\) . \(B\) ,元素个数分别为 \(n\) , \(m\) \((2 \le n,m \le 50)\) .数列中所有元素大小均在 \(-10^{9}\) 到 \( ...
- 关于Struts2的通配方法、转发重定向
1.通配符 在配置struts.xml文件的时候,需要很多action,这时可以用到通配符找到与之对应的方法和类,当然实际开发中很少用到这种方法 struts.xml: <!--通配方法 *_* ...
- jenkins构建成功,但war包没有发布到tomcat下
如题,jenkins构建成功,在jenkins的workspace中有生成的war包,但没有发布到tomcat的webapps目录. 构建日志 找了很多原因发现应该还是项目相对路径不对导致的,我的wa ...
- 解决angular ui-grid 中添加input date修改日期
需求:在angular ui-grid列表中添加一个日期组件来修改时间. 在angular ui-grid添加了一个html5 date input,后端返回的数据是YYYY-MM-DD,比如:201 ...
- 在Linux服务器非root权限下搭建TensorFlow框架(Anaconda)
今天终于动手折腾实验室的服务器啦!由于权限原因,只能在自己的路径下安装TensorFlow. 1. 下载安装Anaconda 官网下载地址:https://www.anaconda.com/downl ...
- 6种纯css实现loading效果
1. <div id="loadingWrap1"> <span></span> <span></span> <s ...
- JSP页面传值出现中文乱码的问题
在接收值的jsp页面代码的body里添加: <%request.setCharacterEncoding("utf-8"); %> //这里是设置utf-8为jsp页 ...
- cropper截图不压缩PHP上传裁剪后的图片
cropperjs使用不多说网上都有很详细的介绍如下面: https://blog.csdn.net/lxy4239/article/details/78920979 主要讲下使用的经历 裁剪后图片不 ...
- org.hibernate.ObjectNotFoundException: No row with the given identifier exists
维护老系统时出现的问题,出现的原因我简述一下: table1与table2是关联表,T1中有T2的主键 "T1_id",当T1中的 "T2_id" 不为null ...