当对象间存在一对多关系时,则使用观察者模式。比如,当一个对象被修改时,则会自动通知它的依赖对,观察者模式属于行为型模式。
场景
- 关联行为场景,一个对象的改变将导致其他一个或多个对象也发生改变
- 事件多级触发场景,A对象的行为将影响B对象,B对象的行为将影响C对象……
- 跨系统的消息交换场景,如消息队列、事件总线的处理机制
实现
观察者模式核心就一个点,用一个list把观察者保存起来,并提供add和remove观察者,在被观察者变化的时候就遍历并调用list里观察者的方法,核心就是一个list遍历。
观察者模式使用三个类 Subject、Observer 和 Client
Subject
public class Subject {
@Override
public void registerObservers(Observer observer) {
observers.add(observer);
}
@Override
public void unRegisterObservers(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers(String content) {
for (Observer observer : observers) {
observer.update(content);
}
}
}
Observer
public interface Observer {
/**
* 用于更新自身的方法
* @param content 更新的内容
*/
void update(String content);
}
public class Coder implements Observer {
private String mName;
public Coder(String name) {
mName = name;
}
@Override
public void update(String content) {
System.out.println("Hi: " + mName + " " + content);
}
}
Client
public class Client {
public static void main(String[] args) {
Subject infoQ = new Subject();
Coder coder1 = new Coder("linda");
Coder coder2 = new Coder("mary");
Coder coder3 = new Coder("andy");
infoQ.registerObservers(coder1);
infoQ.registerObservers(coder2);
infoQ.registerObservers(coder3);
infoQ.notifyObservers("InfoQ发布新内容了,快来看看吧。");
}
}
优点
- 观察者和被观察者是抽象耦合的,应对业务变化
- 增强系统灵活性、可扩展性
缺点
- 如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间,如果中间有耗时操作,会影响整体效率,所以一般会考虑异步的方式
- 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃
Android 中的应用
- ListView Adapter 数据变化通知,notifyDataSetChanged
- Eventbus 事件总线设计
参考
技术文章:菜鸟教程-设计模式、设计模式系列——观察者模式