概念:定义了对象之间一种多依赖关系,当一个对象的状态发生改变时,它所依赖的对象全部得到通知,并自动更新。又称为发布-订阅模式。
角色:
Subject: 目标类,它是指被观察的对象,内部定义了一个观察者集合,一个目标类可以接受任意数量的观察者对象进行观察,提供了一系列方法的增加和删除观察者对象,同时它定义了通知方法notify();
ConcreteSubject:具体目标类是目标类的子类,通常它包含经常发生改变的数据,当它的状态发生改变的时候,可以向各个观察者发出通知。
Observer:抽象观察者,观察者将对观察者的改变做出反应,观察者一般声明为接口,其中定义了更新数据的方法update()。
ConcreteObserver:具体观察者是抽象观察者的子类,它实现了抽象观察的update()方法。
主要优点:
观察者模式在观察目标和观察者之间建立一个抽象的耦合。观察目标只需要维持一个抽象观察者的集合,无须了解其具体观察者。
观察者模式满足“开闭原则”的要求,增加新的具体观察者无须修改原有系统代码。
主要缺点
如果一个观察目标对象有很多直接和间接观察者,所有的观察者都通知到会花费很多时间。
如果在观察者和观察目标之间存在循环依赖,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
Android中的应用:
DataSetObserver:抽象观察者,Observer
AdapterDataSetObserver: 具体观察者,ConcreteObserver
Subject:观察目标,BaseAdapter。
ConcreteSubject:具体的观察目标,ConcreteBaseAdapter。
ConcreteBaseAdapter继承BaseAdapter
AdapterDataSetObserver继承DataSetObserver
在BaseAdapter的内部维持了一个DataSetObserver(数据集观察者),并且提供了相应的方法来注册和解注册观察者。在setAdapter()这个方法的内部会注册观察者。
当ListView的数据集发生改变的时候,会调用Adapter的notifyDataSetChanged函数,这个函数会调用DataSetObeserver的notifyChanged()函数,在这个函数的内部又会调用所有观察者的(AdapterDataSetObserverChange())方法。在onChanged函数中会调用ListView的重新布局函数刷新界面。
适用场景:
一个对象的改变将导致一个或多个其他对象也发生改变,而并不知道具体有多少对象将发生改变,也不知道这些对象是谁。