有趣的事情发生时,可千万别错过了!有一个模式可以帮你的对象知悉现况,不会错过该对象感兴趣的事。对象甚至在运行时可决定是否要继续被通知。有了观察者,你将会消息灵通。

介绍

观察者模式的定义:

在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会收到通知,并自动更新。

简单理解

为了方便理解观察者模式,我们以报社为例:

  1. 报社的业务是出版报纸;
  2. 向某家报社订阅报纸,只要他们有新报纸出版,就会给你送来。只要你是他们的订户,你就会一直收到新报纸。
  3. 当你不想再看报纸的时候,取消订阅,他们就不会再送新报纸来。
  4. 只要报社还在运营,就会一直有人(或单位)

如果你了解报社的订阅是怎么回事,其实就知道观察者是怎么回事了,只是名称不太一样:

出版者改称为“主题”(Subject)或“被观察者”(Observable),订阅者改称为“观察者”(Observer).

主题 + 观察者 = 观察者模式

主题就是定义中的“一”,观察者为定义中的“多”,当主题有变化时,便会通知它的”订阅者“也就是”观察者“

使用场景

  • 一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
  • 一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
  • 一个对象必须通知其他对象,而并不知道这些对象是谁。
  • 需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。

举例:有一个微信公众号服务,不定时发布一些消息,关注公众号就可以收到推送消息,取消关注就收不到推送消息。

优缺点

优点

  1. 观察者和被观察者是抽象松耦合的;
  2. 建立一套触发机制。

缺点

  1. 如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间;
  2. 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。

注意事项

  1. JAVA 中已经有了对观察者模式的支持类;
  2. 避免循环引用;
  3. 如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。

实现

类图

实现步骤

创建抽象主题 - Subject

public interface Subject {

	//观察者订阅服务
public void registerObserver(Observer o); //观察者取消订阅服务
public void removeObserver(Observer o); //主题改变时,会被调用,通知所有观察者
public void notifyObservers(); }

创建抽象观察者 - Observer

public interface Observer {

	public void update(float temp, float humidity, float pressure);

}

创建具体主题

public class WeatherData implements Subject {
private ArrayList<Observer> observers;
private float temperature;
private float humidity;
private float pressure; public WeatherData() {
observers = new ArrayList<Observer>();
} public void registerObserver(Observer o) {
observers.add(o);
} public void removeObserver(Observer o) {
int i = observers.indexOf(o);
if (i >= 0) {
observers.remove(i);
}
} public void notifyObservers() {
for (Observer observer : observers) {
observer.update(temperature, humidity, pressure);
}
} public void measurementsChanged() {
notifyObservers();
} public void setMeasurements(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
this.pressure = pressure;
measurementsChanged();
} // public float getTemperature() {
// return temperature;
// }
//
// public float getHumidity() {
// return humidity;
// }
//
// public float getPressure() {
// return pressure;
// } }

创建一个具体观察者

public class CurrentConditionsDisplay implements Observer {
private float temperature;
private float humidity;
private Subject weatherData; public CurrentConditionsDisplay(Subject weatherData) {
this.weatherData = weatherData;
//订阅
weatherData.registerObserver(this);
} public void update(float temperature, float humidity, float pressure) {
this.temperature = temperature;
this.humidity = humidity;
display();
} public void display() {
System.out.println("Current conditions: " + temperature
+ "F degrees and " + humidity + "% humidity");
}
}

测试

public class WeatherStation {

	public static void main(String[] args) {

		//创建主题
WeatherData weatherData = new WeatherData(); //创建观察者并订阅
CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);
// StatisticsDisplay statisticsDisplay = new StatisticsDisplay(weatherData);
// ForecastDisplay forecastDisplay = new ForecastDisplay(weatherData); //通知观察者
weatherData.setMeasurements(80, 65, 30.4f);
// weatherData.setMeasurements(82, 70, 29.2f);
// weatherData.setMeasurements(78, 90, 29.2f);
}
}

结语

设计模式源于生活

JAVA设计模式之观察者模式 - Observer的更多相关文章

  1. java设计模式解析(1) Observer观察者模式

      设计模式系列文章 java设计模式解析(1) Observer观察者模式 java设计模式解析(2) Proxy代理模式 java设计模式解析(3) Factory工厂模式 java设计模式解析( ...

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

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

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

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

  4. 理解java设计模式之观察者模式

    在生活实际中,我们经常会遇到关注一个事物数据变化的情况,例如生活中的温度记录仪,当温度变化时,我们观察它温度变化的曲线,温度记录日志等.对于这一类问题,很接近java设计模式里面的“观察者模式”,它适 ...

  5. 人人都会设计模式:观察者模式--Observer

    https://segmentfault.com/a/1190000012295887 观察者模式是抽像通知者和观察者,达到具体通知者跟具体观察者没有偶合.能达到不管是切换通知者,或者是切换观察者,都 ...

  6. java设计模式之观察者模式以及在java中作用

    观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式.模型-视图(Model/View)模式.源-监听器(Source/Listener)模式或从属者(Dependen ...

  7. java设计模式02观察者模式

    观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己. 这里主要讲一下学习内置观察者的记录,在JA ...

  8. 17.java设计模式之观察者模式

    基本需求: 气象站可以将每天测量到的温度,湿度,气压等等,以公告的形式发布出去(比如发布到自己的网站或第三方) 需要设计开放型API,便于其他第三方也能接入气象站获取数据 提供温度.气压和湿度的接口 ...

  9. 二十四种设计模式:观察者模式(Observer Pattern)

    观察者模式(Observer Pattern) 介绍定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新. 示例有一个Message实体类,某些对象 ...

随机推荐

  1. 让Spinner中的文字居中

    如果套用simple_spinner_item或是simple_spinner_dropdown_item,然后直接在Spinner中用 android:gravity="center&qu ...

  2. spellchecker inspection helps locate typeos and misspelling in your code, comments and literals, and fix them in one click

    项目layout文件中出现 spellchecker inspection helps locate typos and misspelling in your code, comments and ...

  3. web数据存储

    数据的存储必然是任何网站必须经历的事,我们可以将数据存放在不同地方,数据库.文件.内存.程序本身.cookie,session中都可以,但是只要需要持久化保留的数据,那么最终肯定还是落在磁盘之上的,我 ...

  4. ERROR (UnicodeEncodeError): 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128

    ERROR (UnicodeEncodeError): 'ascii' codec can't encode characters in position 0-1: ordinal not in ra ...

  5. json : json数据解析(一)

    在项目中经常用到json格式的数据转换与解析,先前写过一些小例子,现在整理下,以备后用和帮助后来者. 言归正传: 使用到的jar包 :json-lib-2.4-jdk15.jar,当然你也可以用自己版 ...

  6. Android开发--环境搭建和调试技巧

    一:环境搭建 (1)我使用的环境是:window8+Java SDK+Eclipse+Android SDK+ADT 安装步骤:Java SDK-->Eclipse--->ADT---&g ...

  7. ECMAScript 6 &ECMAScript 5(在线手册)

    https://www.w3.org/html/ig/zh/wiki/ES5#.E8.A1.A8.E8.BE.BE.E5.BC.8F      ECMAScript 5(在线手册) http://es ...

  8. 读取spring boot项目中resource目录下的文件

    在开发中, 我们常常要将我们的配置文件或者模板文件放在我们的resource目录中. 如下 而在spring boot的项目中, 我们运行的是一个jar包, 并没有解压 所以当我们使用以下方式获取文件 ...

  9. HDU-2616

    Kill the monster Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  10. POJ-3629

    Card Stacking Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3927   Accepted: 1541 Des ...