学习设计模式已经有段时间了,这是总结的第一篇博客,文中有错误、漏洞之处,望各位支出,改正。
观察者模式
一、基本定义
何谓观察者模式?观察者模式定义了对象之间的一对多依赖关系,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并且自动更新。
在这里,发生改变的对象称之为观察目标,而被通知的对象称之为观察者。一个观察目标可以对应多个观察者,而且这些观察者之间没有相互联系,所以么可以根据需要增加和删除观察者,使得系统更易于扩展。
观察者模式又称为发布-订阅模式。
二、基本结构
首先先看观察者模式的UML类图。
分析:
Subject:目标。他把所有对观察者对戏的引用保存在一个聚集里,每一个主题都可以有多个观察者。
Observer:观察者。为所有的具体观察者定义一个接口,在得到主题的通知时能够及时的更新自己。
ConcreteSubject:具体主题。将有关状态存入具体观察者对象。在具体主题发生改变时,给所有的观察者发出通知。
ConcreteObserver:具体观察者。实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态相协调。
三、实现观察者模式
情景是这样的:在气象观测站中,它能够追踪目前的天气状况,包括温度、适度、气压。需要实现一个布告板,能够分别显示目前的状态,气象统计和简单的预报。当气象站中获取最新的测量数据时,三种布告板必须实时更新。
下面是这个案例的设计图:
编码实现:
主题接口 Subject.java
public interface Subject {
/**
* 注册观察者
* @param observer
*/
public void registerObserver(Observer observer);
/**
* 删除观察者
* @param observer
*/
public void removeOberver(Observer observer);
/**
* 当主题状态发生改变时,这个方法需要被调用,以通知所有观察者
*/
public void notifyObserver();
}
观察者接口 Observer.java
public interface Observer {
public void update(float temp,float humidity,float pressure);
}
布告板显示接口 DisplayElement.java
public interface DisplayElement {
public void display();
}
WeatherData实现主题接口 WeatherData.java
public class WeatherData implements Subject{
private List<Observer> observers;
private float tempterature;
private float pressure;
private float humidity;
public WeatherData(){
observers = new ArrayList<Observer>();
}
@Override
public void notifyObserver() {
for(int i = 0; i < observers.size();i++){
Observer observer = observers.get(i);
observer.update(tempterature, humidity, pressure);
}
}
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeOberver(Observer observer) {
int i = observers.indexOf(observer);
if(i >= 0){
observers.remove(i);
}
}
/**
* 气象站得到更新的观测数据时,通知观察者
*/
public void measurementChanged(){
notifyObserver();
}
public void setMeasurements(float temperature,float humidity,float pressure){
this.tempterature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementChanged();
}
}
布告板 CurrentCondituonDisplay.java
public class CurrentConditionsDisplay implements Observer,DisplayElement{
private float temperature;
private float humidity;
private Subject weatherData;
public CurrentConditionsDisplay(Subject weatherData){
this.weatherData = weatherData;
weatherData.registerObserver(this); //注册观察者
}
public void update(float temp, float humidity, float pressure) {
this.temperature = temp;
this.humidity = humidity;
display();
}
@Override
public void display() {
System.out.println("Current conditions:"+temperature+"F degrees and "+humidity+"% humidity");
}
}
测试程序 WeatherStation
public class WeatherStation {
public static void main(String[] args) {
WeatherData weatherData = new WeatherData();
CurrentConditionsDisplay conditionsDisplay = new CurrentConditionsDisplay(weatherData);
weatherData.setMeasurements(80, 65, 30.4f);
weatherData.setMeasurements(82, 70, 29.2f);
weatherData.setMeasurements(78, 78, 40.4f);
}
}
运行过程
四、观察者模式的优缺点
优点:
1、当两个对象之间送耦合,他们依然可以交互,但是不太清楚彼此的细节。观察者模式提供了一种对象设计,让主题和观察者之间送耦合。主题所知道只是一个具体的观察者列表,每一个具体观察者都符合一个抽象观察者的接口。主题并不认识任何一个具体的观察者,它只知道他们都有一个共同的接口。
2、观察者模式支持“广播通信”。主题会向所有的观察者发出通知。
3、观察者模式符合“开闭原则”的要求。
缺点:
1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
2、 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进 行循环调用,可能导致系统崩溃。
3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
五、观察者模式的适用场所
1、一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
2、一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
3、一个对象必须通知其他对象,而并不知道这些对象是谁。需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。
总结
1、观察者模式定义了对象之间的一对多关系。多个观察者监听同一个被观察者,当该被观察者的状态发生改变时,会通知所有的观察者。
2、观察者模式中包含四个角色。主题,它指被观察的对象。具体主题是主题子类,通常它包含有经常发生改变的数据,当它的状态发生改变时,向它的各个观察者发出通知;观察者,将对观察主题的改变做出反应;具体观察者中维护一个指向具体目标对象的引用,它存储具体观察者的有关状态,这些状态需要和具体目标的状态保持一致。
3、主题用一个共同的接口来更新观察者。
4、观察者与被观察者之间用松耦合方式结合。
5、有多个观察者时,不可以依赖特定的通知次序。
6、使用观察者模式,可以从被观察者处推或者拉数据。
该读书笔记的代码和部分语句均来自《Head First 设计模式》
分享到:
相关推荐
HeadFirst 设计模式学习笔记2--观察者模式 demo http://blog.csdn.net/laszloyu/archive/2010/05/12/5581769.aspx
NULL 博文链接:https://mountain-king.iteye.com/blog/720810
行为型模式:模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式) 2) 学习目标:通过学习,学员...
031114_【第11章:Java常用类库】_观察者设计模式笔记
观察者模式笔记1
3. 行为型模式:行为型模式关注对象之间的通信和协作,包括责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式和访问者模式。这些模式可以帮助...
设计模式经典样例笔记与代码Swift.zip 基础 [x] 类间的关系 [x] 设计原则 创建型 这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用 new 运算符直接实例化对象。这使得程序在判断针对某个给定...
3.设计模式Design Pattern:创建型模式(厂模式Factory、抽象工厂模式Abstract Factory、单例模式Singleton、建造者模式Builder、原型模式Prototype和对象池模式Object Pool Pattern)、结构型模式(适配器模式、...
该文档是自己在学习设计模式时整理的常用设计模式pdf文档,包括源码,包括装饰模式,代理模式,责任链模式,命令模式,解释器模式,迭代器模式,备忘录模式,观察者模式,工厂模式,建造者模式,适配器模式,桥梁...
2.1观察者模式(不依赖jdk) 博文链接:https://biaowen.iteye.com/blog/505950
在PHP学习中,收集了一些常用的编程方法和思想,集中详细的记录了9种设计模式的设计思路和用法。比如:工厂模式,单例模式,注册模式,适配器模式,观察者模式等
Java Design PatternsJava 设计模式学习笔记,简单易懂,每个模式都有相应的代码示列,帮助学习理解。在线阅读地址:设计原则创建型模式作用:将创建与使用代码解耦结构型模式作用:将不同的功能代码解耦桥接模式...
设计模式(Design Pattern)是前辈们对代码开发经验的总结,是解决特定问题的一系列套路。它不是语法规定,而是一套用来提高代码可复用性、可维护性、可读性、稳健性以及安全性的解决方案。工厂模式、抽象工厂模式、...
Android源码设计模式解析与实战读书笔记源代码 说明: 包名factorypattern.normal表示的是工厂方法模式的普通用法 包名factorypattern.practices表示的是工厂方法模式的常用 包名observerpattern表示的是观察者模式...
本人的笔记,关于java基础中设计模式的内容 包括 1.作业回顾 2.内部类 2.1局部内部类 2.2静态内部类 2.3匿名内部类 3.设计模式 3.1单例模式 3.2代理模式 3.3观察者模式 3.4模板模式 4.练习
describe:设计模式学习笔记 逻辑结构图 代码结构图 设计模式简述 创建型模式,共五种:工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式。 结构型模式,共七种:适配器模式,装饰器模式,代理模式,...
是我在学习设计模式时整理的,其中一些是我自己学习,很多来自网络.希望对模式有兴趣的朋友有帮助,我会很高兴.
Essential .NET 读书笔记 [第一部分] NET FrameWork的Collections支持 .NET的反射在软件设计上的应用 关于跨程序集的反射 实现C#和VB.net之间的相互转换 深入剖析ASP.NET组件设计]一书第三章关于ASP.NET运行原理讲述...
比如单例设计模式、工厂设计模式、观察者模式、MVC框架结构设计模式等。 接下来我们一起来学习PHP中最常用的三种设计模式:单例设计模式、工厂设计模式和观察者设计模式。 单例设计模式 所谓单例模式,即在应用程序...