观察者模式的定义
观察者模式就是定义了对象之间的一对多依赖关系,当一个对象的状态改变的时候,它的所有依赖者都会收到这个改变状态的通知,并且更新。总的来说,自己就是一个服务端,下面有许多的客户,当自己这边有改动的时候,属于自己的客户都会知道这个消息。观察者模式的别名包括发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。观察者模式是一种对象行为型模式。
根据这个定义,请看下面的这个图片做对照
在图片中,很明显的表现出来一种一对多的关系,观察者的集合依赖于服务的对象,只要服务的对象一有改变,那么观察者集合就会收到消息并且更新。
类图
观察者模式结构中通常包括观察目标和观察者两个继承层次结构,如下图
在观察者模式结构图中包含如下几个角色:
- Subject(目标):目标又称为主题,它是指被观察的对象。在目标中定义了一个观察者集合,一个观察目标可以接受任意数量的观察者来观察,它提供一系列方法来增加和删除观察者对象,同时它定义了通知方法notify()。目标类可以是接口,也可以是抽象类或具体类。
- ConcreteSubject(具体目标):具体目标是目标类的子类,通常它包含有经常发生改变的数据,当它的状态发生改变时,向它的各个观察者发出通知;同时它还实现了在目标类中定义的抽象业务逻辑方法(如果有的话)。如果无须扩展目标类,则具体目标类可以省略。
- Observer(观察者):观察者将对观察目标的改变做出反应,观察者一般定义为接口,该接口声明了更新数据的方法update(),因此又称为抽象观察者。
- ConcreteObserver(具体观察者):在具体观察者中维护一个指向具体目标对象的引用,它存储具体观察者的有关状态,这些状态需要和具体目标的状态保持一致;它实现了在抽象观察者Observer中定义的update()方法。通常在实现时,可以调用具体目标类的attach()方法将自己添加到目标类的集合中或通过detach()方法将自己从目标类的集合中删除。
下面用代码的形式来表示该模型
首先是主题类
public interface Subject {
public void register(Observer o);
public void remove(Observer o);
public void notify();
}
具体目标类ConcreteSubject是实现了目标类Subject
class ConcreteSubject implements Subject
{ // 定义一个集合来保存观察者
private ArrayList observers;
@Override
public void register(Observer o) {
observers.add(o);
}
@Override
public void remove(Observer o) {
int i = observers.indexOf(o);
if(i >= 0 )
{
observers.remove(i);
}
}
@Override
public void notify() {
//遍历观察者集合,调用每一个观察者的响应方法
for(Object obs:observers) {
((Observer)obs).update();
}
}
}
抽象观察者角色一般定义为一个接口,通常只声明一个update()方法,为不同观察者的更新(响应)行为定义相同的接口,这个方法在其子类中实现,不同的观察者具有不同的响应方法
public interface Observer {
//声明响应方法
public void update();
}
在具体观察者ConcreteObserver中实现了update()方法,其典型代码如下所示:
class ConcreteObserver implements Observer {
//实现响应方法
public void update() {
//具体响应代码
}
}
在最后,要注意的是,在观察者模式中,会改变的是主题的状态,主题和观察者都可以使用接口,因为这样可以是两者之间的运作正常,又同时具有松耦合的优点。