设计模式之观察者模式

【定义-Intent】Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. 定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

【场景】比如现在我作为公司的MM情报员,关注公司MM动态,这时公司的其他同事只要在我这里订阅一下,已有MM最新动态,我就及时邮件通知各位,供各位琢思。

【UML】


【代码】

#include <iostream>

using namespace std;

const int MAX_OBSERVER = 0x20;

typedef enum _State 
{
    STATE_ONE,
    STATE_TWO,
    STATE_THREE,
    STATE_MAX
} State;

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

class Subject
{
protected:
    Observer* observers[MAX_OBSERVER];
public:
    Subject()
    {
        memset(observers, 0, MAX_OBSERVER * sizeof(Observer*));
    }
    virtual void attach(Observer* observer)
    {
        for(int i = 0; i < MAX_OBSERVER; ++i)
        {
            if(0 == observers[i])
            {
                observers[i] = observer;
                break;
            }
        }
    }
    virtual void detach(Observer* observer)
    {
        for(int i = 0; i < MAX_OBSERVER; ++i)
        {
            if(observer == observers[i])
            {
                observers[i] = 0;
                break;
            }
        }
    }

    virtual void notify()
    {
        for(int i = 0; i < MAX_OBSERVER; ++i)
        {
            if(0 != observers[i])
            {
                observers[i]->update();
            }
        }
    }
};

class ConcreteSubject : public Subject
{
private:
    State state;
public:
    State getState()
    {
        return state;
    }

    void setState(State s)
    {
        this->state = s;
    }
};

class ConcreteObserver : public Observer
{
private:
    char name[32];
    ConcreteSubject* subObjuect;
    State state;
public:
    ConcreteObserver(ConcreteSubject* sub, char* n)
    {
        memset(name, 0, 32);
        this->subObjuect = sub;
        sprintf(name, n);
    }
    void update()
    {
        this->state = subObjuect->getState();
        cout<<"Name:"<<name<<" State:"<<state<<endl;
    }
};

int main()
{
    ConcreteSubject* subject = new ConcreteSubject;
    ConcreteObserver* one = new ConcreteObserver(subject, "One");
    ConcreteObserver* two = new ConcreteObserver(subject, "Two");

    subject->attach(one);
    subject->attach(two);

    subject->setState(STATE_ONE);
    subject->notify();

    subject->detach(one);
    subject->setState(STATE_THREE);
    subject->notify();

    delete subject;
    delete one;
    delete two;

    return 0;
}


posted @ 2012-06-11 16:13  $逝水无痕$  阅读(116)  评论(0编辑  收藏  举报