一、什么是观察者模式:

观察者模式又称为 发布-订阅模式,定义了对象之间一对多依赖关系,当目标对象(被观察者)的状态发生改变时,它的所有依赖者(观察者)都会收到通知。一个观察目标可以对应多个观察者,而这些观察者之间没有相互联系,所以能够根据需要增加和删除观察者,使得系统更易于扩展,符合开闭原则;并且观察者模式让目标对象和观察者松耦合,虽然彼此不清楚对方的细节,但依然可以交互,目标对象只知道一个具体的观察者列表,但并不认识任何一个具体的观察者,它只知道他们都有一个共同的接口。

但观察者模式的缺点在于如果存在很多个被观察者的话,那么将需要花费一定时间通知所有的观察者,如果观察者与被观察者之间存在循环依赖的话,那么可能导致系统崩溃,并且观察者模式没有相应的机制让观察者知道被观察对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

二、UML 结构图:

Subject:抽象主题(被观察者),每一个主题可以有多个观察者,并将所有观察者对象的引用保存在一个集合里,被观察者提供一个接口,可以增加和删除观察者角色

ConcreteSubject:具体主题,将有关状态存入具体观察者对象,在主题发生改变时,给所有的观察者发出通知

Observer:抽象观察者,为所有的具体观察者定义一个更新接口,该接口的作用是在收到主题的通知时能够及时的更新自己

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>();}@Overridepublic void notifyObserver() {for(int i = 0; i < observers.size();i++){Observer observer = observers.get(i);observer.update(tempterature, humidity, pressure);}}@Overridepublic void registerObserver(Observer observer) {observers.add(observer);}@Overridepublic 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();}@Overridepublic 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)推送模式:目标角色发生变化时,通知观察者的同时,通过参数将变化的细节传递到观察者角色中去。

这两种模式的使用取决于系统设计,如果目标角色比较复杂,并且观察者角色进行更新时必须得到一些具体变化的信息,则“推模式”比较合适,如果目标角色比较简单,则“拉模式”就很合适啦。


设计模式系列文章:

Java设计模式之创建型:工厂模式详解(简单工厂+工厂方法+抽象工厂)

Java设计模式之创建型:建造者模式

Java设计模式之创建型:单例模式

Java设计模式之创建型:原型模式

Java设计模式之结构型:适配器模式

Java设计模式之结构型:装饰器模式

Java设计模式之结构型:代理模式

Java设计模式之结构型:桥接模式

Java设计模式之结构型:外观模式

Java设计模式之结构型:组合模式

Java设计模式之结构型:享元模式

Java设计模式之行为型:策略模式

Java设计模式之行为型:模板方法模式

Java设计模式之行为型:责任链模式

Java设计模式之行为型:观察者模式

Java设计模式之行为型:访问者模式

Java设计模式之行为型:中介者模式

Java设计模式之行为型:命令模式

Java设计模式之行为型:状态模式

Java设计模式之行为型:备忘录模式

Java设计模式之行为型:迭代器模式

Java设计模式之行为型:解释器模式

Java设计模式之行为型:观察者模式相关推荐

  1. Java设计模式之行为型:解释器模式

    一.什么是解释器模式:         解释器模式,就是定义语言的文法,并建立一个解释器来解释该语言中的句子,通过构建解释器,解决某一频繁发生的特定类型问题实例. 这里我们将语言理解成使用规定格式和语 ...

  2. Java设计模式之行为型:访问者模式

    背景: 去医院看病时,医生会给你一个处方单要你去拿药,拿药我们可以分为两步走: (1)去柜台交钱,划价人员会根据处方单上的药进行划价,交钱. (2)去药房拿药,药房工作者同样根据处方单给你相对应的药. ...

  3. Java设计模式之行为型:状态模式

    背景: 介绍状态模式前,我们先看这样一个实例:公司力排万难终于获得某个酒店的系统开发项目,并且最终落到了你的头上.下图是他们系统的主要工作: 当第一眼看到这个系统时你就看出这是一个状态图,每个框都代表 ...

  4. Java设计模式之行为型:备忘录模式

    在开发过程中,经常需要保存对象的中间状态,当需要的时候,可以恢复到这个状态.比如,在编程时假如编写失误,例如不小心误删除了几行代码,我们希望返回删除前的状态,便可以使用 Ctrl+Z 来进行返回,这时 ...

  5. Java设计模式之行为型:命令模式

    前言: 在开发中,我们可能需要向某些对象发送一些请求,但我们不知道请求的具体接收者是谁,也不知道被请求的操作是哪个,只知道在系统运行中指定具体的请求接收者即可,打个比方,电视遥控器,我们只需知道按哪个 ...

  6. Java设计模式之行为型:责任链模式

    背景: 学校规定参加校招的同学必须要请假,且要有相关人员的签字,三天以下需辅导员签字.三到七天需要系主任签字,一个星期以上需要院长签字,更多的则需要校长签字! 上图将学生.辅导员.系主任.院长.校长组 ...

  7. Java设计模式之行为型:迭代器模式

    一.什么是迭代器模式: 实际开发中,我们针对不同的需求,可能需要以不同的方式来遍历整个整合对象,但我们不希望在集合容器的抽象接口层中充斥着各种不同的遍历操作,这时候我们就需要一种能完成下面功能的迭代器 ...

  8. Java设计模式之行为型:模板方法模式

    一.什么是模板方法模式: 模板方法是基于继承实现的,在抽象父类中声明一个模板方法,并在模板方法中定义算法的执行步骤(即算法骨架).在模板方法模式中,可以将子类共性的部分放在父类中实现,而特性的部分延迟 ...

  9. Java设计模式之行为型:策略模式

    一.背景: 在开发中经常遇到这种情况,实现某个功能有多种算法策略,我们可以根据不同环境或者条件选择不同的算法策略来完成该功能,比如查找.排序等,一种常用方式是硬编码在一个类中,如需要提供多种查找算法, ...

最新文章

  1. Linux使用百度云
  2. ASP.NET常见错误,原因及解决方法(2003版)_不断更新.....
  3. python入门代码示例-Python入门100个实例(14)——换行符和制表符
  4. JavaScript快速入门-ECMAScript本地对象(String)
  5. 电子表格控件Aspose.Cells V17.4.0发布 | 新增重要功能
  6. aggs 聚合 取结果
  7. WebService—实现接口发布和客户端调用的几种方式
  8. perl:非贪婪的数量词
  9. JSON与JAVA的数据转换
  10. SQL盲注篇之布尔盲注
  11. 教学设计和反思高中计算机,高中信息技术教学反思
  12. JavaScript里函数中的this
  13. c语言打印星号对勾,Intellij常用快捷键记录
  14. PIC16F887 单片机 信号发生器 波形发生器 PCF8591
  15. 问卷设计中 你经常使用计算机吗,计算机应用基础课程调查问卷
  16. ceph16 rbd加密
  17. Codeforces Gym 100015G Guessing Game 差分约束
  18. 伪随机生成器具体实现——杂乱的方法
  19. ping命令基本使用详解
  20. DOM基础笔记——DOMTokenList

热门文章

  1. 网上开店完全指导手册
  2. vs.net2005技术总结
  3. Python之虚拟环境venv实战详解
  4. layui跳转页面传递数据
  5. 今日科技联播:阿里巴巴成立“平头哥”半导体公司;美团点评发行价每股69港元...
  6. 【每天学点管理】——以矛盾激发思维的“头脑风暴”
  7. EXCEL如何快速在多个不同位置单元格求和
  8. H5移动端调用手机摄像头
  9. python版 常用排序算法 思路加详解 冒泡排序、快速排序、插入排序、选择排序
  10. 虚拟机系统 无网络连接网络连接网络连接服务器,Win10虚拟机无法连接网络怎么解决?...