前言:
Android 的设计模式系列文章,欢迎star,持续更新。。。
定义:
观察者模式定义对象间的依赖关系,使得每当一个对象改变状态,则所有依赖它的对象都会得到通知并且被自动更新。
使用场景:
- 当一个对象的改变需要通知其它对象改变时,而且它不知道具体有多少个对象有待改变时
- 当一个对象必须通知其它对象,而它又不能假定其它对象是谁
- 跨系统的消息交换场景,如消息队列、事件总线的处理机制
代码示例:
我们拿收发快递作为一个例子应该是最形象的了吧。
快递员每次送快递的时候都会往驿站放包裹,然后通过发信息给收件人拿快递,收件人收到短信后就知道有快递到站了,然后会看是不是自己的快递,判断之后再下去取包裹。
这里可能大家会有一个疑问,为什么还要我在判断一下是不是我自己的快递呢,难道不应该是收到短信了,就说明我有一个快递未取呢?
是的没错,观察者模式就是干这么一个事的,驿站就相当于一个机器,你想收到快递就得向机器添加你的信息接收器(订阅),每当有快递来的时候,他会群发而不是点对点的发送。除非你和这个机器解绑(取消订阅)。
/**
* 抽象观察者
*/
public interface Observer {
/**
* 通知具体观察者
* @param postName 快递接收人的名称
*/
void update(String postName);
}
/**
* 具体观察者
* 男生
*/
public class BoyObserver implements Observer {
private String boyName;
/**
* 男生的名字
*
* @param boyName
*/
public BoyObserver(String boyName) {
this.boyName = boyName;
}
@Override
public void update(String postName) {
if (boyName.equals(postName)) {
System.out.println(boyName + "收到信息,确认这个自己的快递,去拿了");
} else {
System.out.println(boyName + "收到信息,但是不是自己的快递");
}
}
}
/**
* 具体观察者
* 女生
*/
public class GirlObserver implements Observer {
private String girlName;
/**
* 女生的名字
*
* @param girlName
*/
public GirlObserver(String girlName) {
this.girlName = girlName;
}
@Override
public void update(String postName) {
if (girlName.equals(postName)) {
System.out.println(girlName + "收到信息,确认这个自己的快递,让二哈去拿了");
} else {
System.out.println(girlName + "收到信息,但是不是自己的快递");
}
}
}
/**
* 被观察者抽象类
*/
public interface Observable {
//添加观察者
void addObserver(Observer observer);
//删除观察者
void delObserver(Observer observer);
//通知观察者
void notify(String postName);
}
/**
* 具体被观察者
*/
public class Postman implements Observable {
private List<Observer> mList = new ArrayList<>();
@Override
public void addObserver(Observer observer) {
mList.add(observer);
}
@Override
public void delObserver(Observer observer) {
mList.remove(observer);
}
@Override
public void notify( String postName) {
for ( Observer observer :mList){
observer.update(postName);
}
}
}
public class ObserverTest {
public static void main(String[] args) {
Observable observable = new Postman();
Observer boyObserver = new BoyObserver("flynn");
Observer girlObserver = new GirlObserver("serlina");
observable.addObserver(boyObserver);
observable.addObserver(girlObserver);
System.out.println("系统消息:有快递到站啦!");
observable.notify("flynn");
System.out.println("系统消息:有快递到站啦!");
//男生取消订阅
observable.delObserver(boyObserver);
observable.notify("serlina");
}
}
结果:
第二次又快递来的时候,我们男生取消了订阅,所以就收不到信息啦 。
优缺点:
- 解除观察者与主题之间的耦合。让耦合的双方都依赖于抽象,而不是依赖具体。从而使得各自的变化都不会影响另一边的变化。
- 易于扩展,对同一主题新增观察者时无需修改原有代码。
- 依赖关系并未完全解除,抽象主题仍然依赖抽象观察者。
- 会引起多余的数据通知。
- 使用观察者模式时需要考虑一下开发效率和运行效率的问题,程序中包括一个被观察者、多个观察者,开发、调试等内容会比较复杂,而且在Java中消息的通知一般是顺序执行,那么一个观察者卡顿,会影响整体的执行效率,在这种情况下,一般会采用异步实现。
Android 中有很多用到这种模式的:
(1)、Listener监听:setOnClickListener
(2)、Adapter的notifyDataSetChanged()方法
(3)、BroadcastReceiver
(4)、EventBus,RxBus,RxJava,RxAndroid,等库。
具体源码我就不贴啦,大家有兴趣可以自己查阅哦。