JAVA设计模式之观察者模式 - Observer

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

介绍

观察者模式的定义:

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

简单理解

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

  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);
}
}

结语

设计模式源于生活

(0)

相关推荐

  • 图解Java设计模式之观察者模式

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

  • JAVA设计模式之观察者模式

    JAVA设计模式之观察者模式

  • 设计模式之观察者模式(observer pattern)

    观察者模式主要用于处理对象间的一对多的关系,是一种对象行为模式.该模式的实际应用场景比较容易确认,当一个对象状态发生变化时,所有该对象的关注者均能收到状态变化通知,以进行相应的处理. 本文希望通过简单 ...

  • Java设计模式【命令模式】

    命令模式 命令模式很好理解,举个例子,司令员下令让士兵去干件事情,从整个事情的角度来考虑,司令员的作用是,发出口令,口令经过传递,传到了士兵耳朵里,士兵去执行.这个过程好在,三者相互解耦,任何一方都不 ...

  • 免费下载《Java设计模式(第2版)》.pdf

    回复"面试"获取全套面试资料 设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用. 设计模式是软件开发人员在软件开发过程中面临的一 ...

  • PHP设计模式之观察者模式

    PHP设计模式之观察者模式 观察者,貌似在很多科幻作品中都会有这个角色的出现.比如我很喜欢的一部美剧<危机边缘>,在这个剧集中,观察者不停的穿越时空记录着各种各样的人或事.但是,设计模式中 ...

  • [PHP小课堂]PHP设计模式之观察者模式

    [PHP小课堂]PHP设计模式之观察者模式 关注公众号:[硬核项目经理]获取最新文章 添加微信/QQ好友:[DarkMatterZyCoder/149844827]免费得PHP.项目管理学习资料

  • java设计模式基础--拦截器

    由于动态代理一般比较难理解,一般都会设计一个拦截器接口供开发者使用,这样开发者就只用知道拦截器接口的方法,含义和作用即可,无须知道动态代理是怎么实现的. 以下代码用JDK动态代理来实现一个拦截器的逻辑 ...

  • java设计模式基础--动态代理

    动态代理的意义在于生成一个代理对象,来代理真实对象,从而控制真实对象的访问.比如你是以为软件工程师,客户带着需求去找公司,显然不会直接和你谈,而是去找商务,此时客户认为商务就代表公司.商务(代理对象) ...