1. 定义
定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新
2. 使用场景:
- 关联行为,事件多级触发,跨系统的消息交换(消息队列,事件总线)等
- 常用于GUI系统,订阅发布系统
3. 优缺点
- 优点:解耦,减小依赖性,灵活,可扩展
- 缺点:开发和运行效率,一对多调试比较复杂,而且java中的消息通知是默认顺序执行的, 一个观察者卡顿,会影响整体的执行效率,这种情况下一般要考虑异步方式
4. Android源码中的使用
- Observer,Observable是JDK中内置类型,可见观察者模式的重要性
- ListView Adapter的notifyDataSetChanged,setAdapter时中会创建一个数据集的观察者AdapterDataSetObserver,而BaseAdapter中有一个被观察者 DataSetObservable,Adapter的 notifyDataSetChanged 中就是调用了 DataSetObservable 的notifyChanged方法,notifyChanged 中则是遍历了所有观察者(mObservers),并调用他们的onChanged方法
- BroadcastReceiver广播的注册订阅发送,也是典型的观察者模式
- EventBus,RxJava等
5. 实例演示
以程序员经常会看的极客头条的订阅为例。
下面的观察者和被观察者直接继承 JDK中内置的Observer,Observable:
- 创建观察者,即程序员类
//观察者,程序员
class Coder implements Observer {
public String name;
public Coder(String name) {
this.name = name;
}
@Override
public void update(Observable o, Object arg) {
LjyLogUtil.i("hi, " + name + ", 极客头条有文章更新了,更新内容:" + arg);
}
@Override
public String toString() {
return "码农:" + name;
}
}
- 创建被观察者,即文章网站
//极客头条,被观察者
class GeekNews extends Observable {
public void postNews(String content) {
setChanged();
notifyObservers(content);
}
}
- 创建观察者和被观察者对象,进行订阅
private void methodObserverPattern() {
//1.创建被观察者
GeekNews geekNews = new GeekNews();
//2.创建观察者
Coder coder1 = new Coder("马画藤");
Coder coder2 = new Coder("云马");
Coder coder3 = new Coder("王剑灵");
//订阅/注册
geekNews.addObserver(coder1);
geekNews.addObserver(coder2);
geekNews.addObserver(coder3);
//发布消息
geekNews.postNews("最新Android文章-RxJava详解");
geekNews.postNews("最新iOS文章-UIView详解");
}
这里只是简单的演示,要想深入了解观察者模式,可以了解一下EventBus,RxJava等一些开源框架,其中对观察者模式有很明显的体现
网友评论