当对象间存在一对多关系时,则使用观察者模式。比如,当一个对象被修改时,则会自动通知它的依赖对,观察者模式属于行为型模式。
场景
- 关联行为场景,一个对象的改变将导致其他一个或多个对象也发生改变
- 事件多级触发场景,A对象的行为将影响B对象,B对象的行为将影响C对象……
- 跨系统的消息交换场景,如消息队列、事件总线的处理机制
实现
观察者模式核心就一个点,用一个list把观察者保存起来,并提供add和remove观察者,在被观察者变化的时候就遍历并调用list里观察者的方法,核心就是一个list遍历。
观察者模式使用三个类 Subject、Observer 和 Client
Subject
public class Subject {@Overridepublic void registerObservers(Observer observer) {observers.add(observer);}@Overridepublic void unRegisterObservers(Observer observer) {observers.remove(observer);}@Overridepublic 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;}@Overridepublic 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 事件总线设计
参考
技术文章:菜鸟教程-设计模式、设计模式系列——观察者模式
