您的位置:首页 > 编程语言 > C语言/C++

学习设计模式--观察者模式(C++)

2014-07-14 09:17 337 查看
1. 说说简单的函数回调

首先说说一种简单的函数回调机制(一种通过获取对象的指针来进行函数的调用方法)以下是代码演示---

这是观察者(被回调)部分:

class Observer
{
public:
// 抽象观察者的纯虚函数
virtual void UpdateMessage() = 0;
};

class ConcreteObserver : public Observer
{
public:
// 实现抽象类的纯虚函数
void UpdateMessage();
}

void ConcreteObserver::UpdateMessage()
{
// 这里实现详细的操作
}

class Subject
{
public:
Subject(Observer* observer = NULL);

void OnMessageChanged();

private:
Observer* m_observer;
};

以下是被观察者(主动调用)部分:

Subject::Subject(Observer* observer)
{
// 将Observer的对象指针传进来并复制
m_observer = observer;
}

void Subject::OnMessageChanged()
{
if(m_observer)
{
// 通过多态机制下的指针回调观察者的函数
m_observer->UpdateMessage();
}
}


如上所看到的,程序中的一个对象通过获取还有一个对象的指针,来进行函数的调用。这不是类之间的直接调用,仅仅因该对象指针是在多态下定义的。

进一步拓展,假设有一个或多个多个观察者来关注一个或多个对象,那么就能够用通常所说的观察者模式来实现了。

2. 观察者模式的应用场合和特点

观察者模式一般出如今这种场合:存在观察者和被观察对象。详细样例,比方订阅邮件或杂志, 微博关注某某主题等。当你在微博上关注了某个主题后,当这个主题有新的信息发出来时,你的微博主页将会对应收到它的更新信息。

而观察者模式提供了这种一个对象模型,使得对象们(主题和观察者)之间松耦合:

(1)观察者的更替或数据模块的更新不会影响主题的存在。

(2)观察者和主题类能够方便的独立地被程序其它模块使用。

(3)一个主题能够注冊多个观察者,也能够动态删除观察者; 一个观察者也能够注冊多个主题,也能够撤销注冊。

比如一份天气预报能够被多个用户订阅,当数据更新时会通知全部注冊的用户。一个用户也能够订阅多份天气预报,广州的,珠海的等等。

3.简单的代码演示

(1)演示的功能能够用这个类图来表达,类图中定义了Subject和Observer两个接口,并定义了两个详细主题类和三个详细观察者类。



(2)详细代码实现

首先是主题类,分别定义了类ConcreteSubjectA和类ConcreteSubjectB。

class Subject
{
public:
virtual void registerObserver(shared_ptr<Observer> observer) = 0;
virtual void removeObserver(shared_ptr<Observer> observer) = 0;
virtual void notifyObserver() = 0;
};

class ConcreteSubjectA : public Subject
{
public:
ConcreteSubjectA()
{
// do something here
testValue = 1;
}

void registerObserver(shared_ptr<Observer> observer)
{
observersList.push_back(observer);
}
void removeObserver(shared_ptr<Observer> observer)
{
observersList.remove(observer);
}

void notifyObserver()
{
for (list<shared_ptr<Observer> >::iterator it = observersList.begin();
it != observersList.end(); ++it)
{
(*it)->updateData(testValue);
}
}

private:
list<shared_ptr<Observer> > observersList;
int testValue;
};

class ConcreteSubjectB : public Subject
{
public:
ConcreteSubjectB()
{
// do something here
testValue = 2;
}

void registerObserver(shared_ptr<Observer> observer)
{
observersList.push_back(observer);
}
void removeObserver(shared_ptr<Observer> observer)
{
observersList.remove(observer);
}

void notifyObserver()
{
for (list<shared_ptr<Observer> >::iterator it = observersList.begin();
it != observersList.end(); ++it)
{
(*it)->updateData(testValue);
}
}

private:
list<shared_ptr<Observer> > observersList;
int testValue;
};
接着是观察者类,分别定义了类ConcreteObserverA,类ConcreteObserveB,类ConcreteObserverC。

class Observer
{
public:
virtual void updateData(int val) = 0;
};

class ConcreteObserverA : public Observer
{
public:
void updateData(int val)
{
// do something here
cout << "In A :" << val <<endl;
}
};

class ConcreteObserverB : public Observer
{
public:
void updateData(int val)
{
// do something here
cout << "In B :" << val <<endl;
}
};

class ConcreteObserverC : public Observer
{
public:
void updateData(int val)
{
// do something here
cout << "In C :" <<val <<endl;
}
};


然后,我们能够这样使用他们:

int main()
{
shared_ptr<Subject> subjectA(new ConcreteSubjectA());
shared_ptr<Subject> subjectB(new ConcreteSubjectB());

shared_ptr<Observer> observerA(new ConcreteObserverA());
shared_ptr<Observer> observerB(new ConcreteObserverB());
shared_ptr<Observer> observerC(new ConcreteObserverC());

subjectA->registerObserver(observerA);
subjectA->registerObserver(observerB);
subjectB->registerObserver(observerC);

// 主题A有更新时将通知观察者A,B
subjectA->notifyObserver();
// 主题B有更新时将通知观察者C
subjectB->notifyObserver();

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: