- 气象站可以将每天测量到的温度、湿度、气压等数据以公告的数据发布出去(比如发布到自己的网站或者第三方)。
- 需要设计开放型api,以便于其他第三方也能接入气象站获取数据。
- 提供温度、湿度、气压等的接口。
- 测量的数据要实时的更新给第三方。
传统方案:
- 通过对气象站项目的分析,我们可以初步设计一个WeatherData类。
- 传统方案代码实现:
package com.xia.designmode.study.observerpattern.tradition;
/**
* 类是核心
* 1.包含最新的天气情况信息。
* 2.含有currentConditions对象。
* 3.当数据有更新时,就主动调用currentConditions对象的update方法。
* */
public class WeatherData {
private float temperature;
private float humidity;
private float pressure;
private CurrentConditions currentConditions;
public WeatherData(CurrentConditions currentConditions) {
this.currentConditions = currentConditions;
}
public void setData(float temperature,float humidity,float pressure){
this.temperature=temperature;
this.humidity=humidity;
this.pressure=pressure;
dataChange();//将信息推送给第三方
}
public void dataChange(){
currentConditions.update(temperature, humidity, pressure);
}
}
- 说明:
- 通过getXXX方法可以让第三方接入,并得到相关消息。
- 当数据有更新时,气象站可以通过dataChange()去更新数据,第三方获得数据时,就能取得最新数据。当然也可以推送。
- 传统方案带来的问题:
- 无法在运行时动态的添加第三方。
- 其他第三方接入气象站获取数据的问题。
观察者模式的应用:
- 观察者模式类似于订牛奶业务
- 奶站/气象局:Subject
- 用户/第三方网站:Observer。
- Subject:登记、移除和通知。
- registerObserver 注册。
- removeObserver 移除。
- notityObervers()通知所有注册的用户,根据不同的需求,可以更新数据,让用户来取,也可以实施推送。看具体需求而定。
- Oberver:接收输入。
观察者模式:对象之间多对一依赖的一种设计方案,被依赖的对象为Subject,依赖的对象为Observer,Subject通知Observer变化,Subject是一的一方,Observer是多的一方。
观察者模式类图:
观察者模式代码实现:
package com.xia.designmode.study.observerpattern.improve;
import java.util.ArrayList;
import java.util.List;
/**
* 类是核心
* 1.包含最新的天气情况信息。
* 2.含有Observer集合对象。
* 3.实现Subject接口,完成对Observer集合的管理。
* */
public class WeatherDataSubject implements Subject{
private float temperature;
private float humidity;
private float pressure;
private List<Observer> observerList; //观察者集合
public WeatherDataSubject() {
observerList=new ArrayList<>();
}
public void setData(float temperature, float humidity, float pressure){
this.temperature=temperature;
this.humidity=humidity;
this.pressure=pressure;
notifyObservers();//将信息推送给第三方
}
//注册观察者
@Override
public void registerObserver(Observer observer) {
observerList.add(observer);
}
//移除观察者
@Override
public void removeObserver(Observer observer) {
observerList.remove(observer);
}
//通知观察者
@Override
public void notifyObservers() {
for (Observer observer:observerList) {
observer.update(this.temperature,this.humidity,this.pressure);
}
}
}
观察者模式的好处:
- 观察者模式设计好后,回忆集合的方式来管理用户(Observer)、包括注册、移除、通知。
- 我们增加一个观察者(可以理解成一个新的公告板)不需要去修改核心WeatherData的代码,遵守ocp原则。
观察者模式在jdk源码Observable中的源码分析:
- JDK的Observable类就是用了观察者模式。
- 代码分析+角色模式分析
- 角色分析和说明:
- Observable相当于Subject接口的具体实现类,管理Observer集合,他并没还有实现一个接口。它实现了核心的方法add、delete、notify。
- Observer的作用和地位等价于我们前面讲到的Observer,有update()。
- Observable和Observer的作用和前面讲的一样,只是Observable是个类。其他子类可以继承来实现观察者模式。
迭代器模式的细节和注意事项:
- 迭代器模式解决了不同集合(比如说ArrayList、LinkedList)的统一遍历问题。
- 迭代器模式提供统一的方法遍历对象,客户端不再考虑聚合的具体类型,使用一种方法就可以遍历对象了。
- 隐藏了聚合的内部结构,客户端要遍历聚合的时候只能取到迭代器,而不知道聚合的具体构成。
- 提供了一种设计思想,就是一个类应该只有一个引起变化的主因(叫单一职责原则)。在聚合类中,我们把迭代器分开,就是要把管理对象集合和遍历对象集合的责任分开,这样一来,集合改变的话只会影响到聚合对象。如果遍历方式改变的话只会影响到迭代器。
- 当要展示一组对象或者遍历一组相同对象时使用。