观察者模式的简单介绍
观察者模式简单的来说就是当一个对象发生改变就会触发另一个对象触发改变,这是一种典型的行为型模式。
在之前的文章中我们介绍过基于事件驱动的编程,观察者模式就是一种典型的基于事件驱动的编程模型。
观察者模式的类图:
观察者模式中各个角色的介绍:
- 抽象主题角色:抽象主题可以用于维护各个注册进来的观察者,以及主题的状态
- 具体主题角色:用于实现抽象主题中的通知方法,当具体主题中的状态发生变化时,通知所有注册过的
- 抽象的观察者:一类观察者的抽象
- 具体的观察者:实现抽象观察者中定义的方法,以便得到主题通知后进行相应的操作
观察者模式的具体实现思路
- 抽象主题的创建
- 具体主题创建,实现通知方式
- 抽象观察者的创建,注意在对象内部发生变的时候需要触发通知方法
- 具体观察者得到通知后,做不同的操作
观察者模式的具体实现方案
//抽象主题
public abstract class Subject {
// 注册到该主题的观察者
private List<Observer> observers = new ArrayList<Observer>();
// 状态
private int state;
// 注册观察者方法
public void add(Observer observer) {
observers.add(observer);
}
// 移除观察者方法
public void remove(Observer observer) {
observers.remove(observer);
}
public int getState() {
return state;
}
// 状态发生变化时,触发通知
public void setState(int state) {
this.state = state;
notifyAllObservers();
}
// 通知所有注册进来观察者的方法
public abstract void notifyAllObservers();
}
// 具体主题
public class ConcreteSubject extends Subject {
public void notifyAllObservers() {
for (Observer observer : observers) {
observer.response();
}
}
}
// 抽象观察者
public interface Observer {
// 观察者的反应
void response();
}
// 具体观察者1
public class ConcreteObserver1 implements Observer {
public void response() {
System.out.println("具体观察者1作出反应!");
}
}
// 具体观察者1
public class ConcreteObserver2 implements Observer {
public void response() {
System.out.println("具体观察者2作出反应!");
}
}
观察者模式的优缺点
优点
- 主题与观察者之间是松耦合的
- 能够灵活的通过主题触发各个观察者,做对应操作
- 支持一对多
缺点
- 观察目标(主题)通知观察者(大量的观察者,或者观察者操作比较复杂)需要耗费较长的时间
- 观察者和观察目标(主题)之间有循环依赖的话,会导致系统奔溃
- 观察者只能知道观察目标发生了变化,但是无法得知怎么发生变化的。
观察者模式的适用场景
- 对象间存在一对多关系,一个对象的状态发生改变会影响其他对象。
- 不需要知道具体观察者是谁,只需分发通知,系统中感兴趣的对象会自动注册,接收该通知。
- 需要在系统中建立触发链,形成一种链式触发机制,使得事件具备跨域(跨越两种观察者类型)通知。
观察者模式总结
观察者模式也是一种主题订阅模式,感兴趣的观察者去订阅主题,主题发生变化,会自动对各个观察者进行通知。这样我们就可以将一些业务逻辑的触,交由一些事件去触发,这也就形成了事件驱动。对事件驱动感兴趣的可以阅读我的这一篇文章https://juejin.cn/post/7030066612162002974,事件驱动对于我们进行程序设计有很大的指导作用,应用也非常广泛。