2_The_Observer_Pattern。
Head First Design Patterns 读书笔记
概念
观察者模式主要的功能是用来解决一类一对多
的关系。
类似于报纸出版商和订阅者关系。
报纸出版(数据更新)会将通知订阅者。订阅者有权取消订阅。当取消订阅就不再接受通知。
Publishers + Subscribers = Observer Pattern
我们叫publisher为SUBJECT, 叫subscribers 为OBSERVERS
当subject更新之后,所有的observers都会被通知。
Subject和observers被定义为一对多的关系。observer是独立于subject的。当subject更新的时候,observer会得到通知。
实现结构:
主要是要定义两个接口:
interface:
-
Subject
- registerObserver()
- removeObserver()
- notifyObserver()
-
Observer
- Update()
对于Subject,需要实现Subject接口。对于所有的观察值,实现Observer的接口。
Implantation:
-
ConcreteSubject
//实现subject接口的方法 -
ConcreteObserver
//实现observer接口的方法
观察者模式的subject和observers是松散耦合。因为
1.subject所知道的关于observer的信息只有一个确定的接口。他并不需要知道其他的信息。
2.我们可以在任何时候都加入新的observer,我们也可以在任何时候删除。
3. 再加入新的类型observer时我们从来都不需要修改subject
4. 我们可以独立的重用subject或observer
5. 在修改subject或者observer不会影响其他的。
准则三
设计准则:Strive for loosely coupled designs between objects that interact.
尽量让相互影响的对象之间的松耦合
应用实例:
例:有一个天气数据,需要实时的显示在三个终端上。当天气的数据发生改变时,终端的显示要进行响应的改变。
/**
*Interface
*/
//Subject.java
public interface Subject {
//用来注册Observer
public void registerObserver(Observer o);
//用来删除注册
public void removeObserver(Observer o);
//用来通知Observers
public void notifyObservers();
}
//Observer.java
/**
* 观察者接口。jdk1.0就有此接口,只是参数些许不同。
* @author Spade
*2019年12月3日
*/
public interface Observer {
/**
* Observer的接口
* @param temp
* @param humidity
* @param pressure
*/
public void update(float temp, float humidity, float pressure);
}
//WeatherData.java
/**
* 因为这个weatherData是subject,所以需要继承Subject的接口。
* @author Spade
*2019年12月3日
*/
public class WeatherData implements Subject{
private List<Observer> observers;
private float temperature;
private float humidity;
private float pressure;
public WeatherData() {
observers = new ArrayList<>();
}
/**
* 注册,将observer放在观察者列表中
*/
@Override
public void registerObserver(Observer o) {
observers.add(o);
}
/**
* 从观察者列表中删除某个observer
*/
@Override
public void removeObserver(Observer o) {
int index = observers.indexOf(o);
if(index >= 0) {
observers.remove(index);
}
}
/**
* 如果更新就通知所有的observer
*/
@Override
public void notifyObservers() {
for (Observer ob : observers) {
ob.update(temperature, humidity, pressure);
}
}
/**
* 用来通知
*/
public void dataChanged() {
notifyObservers();
}
//其他方法,例如data的更新
}
//Display.java
public class Display implements Observer{
private float temperture;
private float humidity;
public Display(Subject weatherData) {
//注意:
//在这里接受weatherData并且注册自己
weatherData.registerObserver(this);
}
/**
* update的实现
*/
@Override
public void update(float temp, float humidity, float pressure) {
this.temperture = temp;
this.humidity = humidity;
//other functions
show();
}
public void show() {
System.out.println("temperture:"+temperture + "humidity"+ humidity);
}
}
//test.java
//测试
public static void main(String[] args) {
//创建一个subject
WeatherData weatherData = new WeatherData();
//创建若干个observer
Display display1 = new Display(weatherData);
Display display2 = new Display(weatherData);
Display display3 = new Display(weatherData);
weatherData.setData(80,45,23.2f);
}