观察者模式

观察者模式定义

观察者模式(Observe Pattern)也叫做发布订阅模式(Publish/subscribe),定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。

观察者模式通用类图

image

Subject被观察者

定义被观察者必须实现的职责,它必须能够动态地增加(Attach),取消观察者(Detach),并通知观察者(Notify)。它一般是抽象类。

Observer 观察者

观察者接收到消息后,即进行update操作,对接收到的信息进行处理。

ConcreteSubject 具体的被观察者

定义被观察者自己的业务逻辑,同时定义对哪些事件进行通知。

ConcreteObserver 具体的观察者

观察者模式的优点

观察者和被观察者之间是抽象耦合

观察者模式通过定义抽象的被观察者基类和观察者基类,从而降低了具体的观察者类和被观察者类之间的耦合。实际的观察操作(绑定,解绑,通知,响应等)都在抽象基类中定义,具体的被观察者和观察者则互相不需要了解对象的实现细节。

建立一套触发机制,可以形成触发链。

缺点

观察者模式需要考虑开发效率和运行效率的问题,一个被观察者,多个观察者,开发和调试就会比较复杂。

举例,在java中已有java.util.Observable实现类和java.util.Observer接口,具体的被观察者类只需要继承Observable类,而观察者只需要实现Observer接口。

C++通用源码:

#include <iostream>
#include <list>

using namespace std;

class Observer{
public:
    virtual void Update()=0;
    virtual ~Observer(){};
};

class Subject{
protected:
    list<Observer *> observers;
public:
    virtual void Attach(Observer *o){observers.push_back(o);};
    virtual void Detach(Observer *o){observers.remove(o);};
    virtual void Notify(){
        for(list<Observer *>::iterator it=observers.begin();it!=observers.end();it++)
        {
            (*it)->Update();
        }
    }
    virtual ~Subject(){};
};

class ConcreteSubject:public Subject{
public:
    ~ConcreteSubject(){
        for(list<Observer *>::iterator it=observers.begin();it!=observers.end();it++)
        {
            delete *it;
        }
    };
    void doSomething(){
        cout<<"具体被观察者在干活,通知观察者..."<<endl;
        Notify();
    }
};

class ConcreteObserver:public Observer{
public:
    void Update(){
        cout<<"被观察者在干活,好样的!"<<endl;
    }
};

class ConcreteObserver1:public Observer{
public:
    void Update(){
        cout<<"咦!还有别的观察者!"<<endl;
    }
};

int main()
{
    ConcreteSubject subject;    //创建被观察者
    subject.Attach(new ConcreteObserver()); //创建一个观察者并绑定到被观察者上
    Observer * observer1 = new ConcreteObserver1();
    subject.Attach(observer1);//创建一个其它子类型的观察者,也绑定到这个被观察者上
    subject.doSomething();  //两个观察者均能收到消息
    subject.Detach(observer1);  //解绑定第二个观察者。
    delete observer1;
    subject.doSomething();
    return 0;
}

运行结果

image

posted @ 2014-06-10 22:19  星辰风  阅读(367)  评论(0编辑  收藏  举报