1. 观察者模式扩展
笔者上篇博客中提到, 对于四人帮定义的标准观察者模式而言, 有两个问题:
- 观察者中需要持有具体观察者的引用,这样导致观察者与被观察者直接有强耦合关系
- 观察者更新方法需要调用被观察者的方法获取实时状态, 虽然这种是为了保证消息通知时最小量化消息的设计,但是在多线程时,我们可能那不到实际触发变更时的状态。因此我们可以此进行改进,观察者的更新方法接收一个参数,接收变化的内容.
1.1 扩展模式-类图
根据上述问题, 笔者将标准观察者模式做以下改动:
- 抽象被观察者模式升级为接口, 保证更通用更灵活
- 具体观察者模式需要实现观察者的管理和通知逻辑,也可在此之间增加一层抽象.
- 观察者角色的更新方法新增参数, 用于传入触发通知方法时的因素
- 具体观察者中不再和被观察者耦合,不再持有对被观察者的引用,更新方法也无须再查询状态.
1.2 被观察者模式-抽象接口
将被观察者模式抽象为接口,对观察者的管理下沉到具体子类.
public interface ISubject {
public void attach(Observer observer);
public void detach(Observer observer);
public void notifyObservers(Object object);
}
1.3 具体被观察者-TemperatureSubject
需要自己实现观察者的管理和通知方法.
public class TemperatureSubject implements ISubject {
// 存储观察者列表
private LinkedList<Observer> observers = new LinkedList<>();
// 保存当前温度
private String temperature;
public void setTemperature(String temperature) {
this.temperature = temperature;
System.out.println("更新当前温度为:" + temperature + " 度");
// 通知观察者
this.notifyObservers(temperature);
}
public String getTemperature() {
return this.temperature;
}
@Override
public void attach(Observer observer) {
this.observers.add(observer);
}
@Override
public void detach(Observer observer) {
this.observers.remove(observer);
}
@Override
public void notifyObservers(Object object) {
this.observers.forEach(observer -> observer.update(object));
}
}
1.4 观察者-Observer
public interface Observer {
// 更新方法: 接收到通知后, 进行更新操作
public void update(Object object);
}
1.5 web观察者-WebObserver
更新方法直接接收到变更的消息,无须再次查询.
public class WebObserver implements Observer {
@Override
public void update(Object temperature) {
System.out.println("Web-接收到消息, 当前温度是:" + temperature + " 度");
}
}
1.6 app观察者-AppObserver
更新方法直接接收到变更的消息,无须再次查询.
public class AppObserver implements Observer {
@Override
public void update(Object temperature) {
System.out.println("App-接收到消息, 当前温度是:" + temperature + " 度");
}
}