参考大话设计模式;
详细内容参见大话设计模式一书第十四章,该书使用C#实现,本实验通过C++语言实现。
观察者模式又叫做发布-订阅(Publish/Subscribe)模式。
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。[DP]
一 学习测试代码
书上的模式学习图
我自己的测试UML图
测试代码:
#include <iostream>
#include <list>
using namespace std;
class guanchazhe{
public:
virtual void update() = 0;
};
class xiaozhang :public guanchazhe{
public:
virtual void update(){
cout << "小张收到" << endl;
}
};
class xiaowang :public guanchazhe{
public:
virtual void update(){
cout << "小王收到" << endl;
}
};
class tongzhizhe{
protected:
list<guanchazhe*> gcz_list;
public:
void attach(guanchazhe *gcz){
gcz_list.push_back(gcz);
}
void detech(guanchazhe *gcz){
gcz_list.remove(gcz);
}
virtual void Notify(){
list<guanchazhe*>::iterator it;
for(it = gcz_list.begin();it != gcz_list.end();it++){
guanchazhe *gcz = (guanchazhe *)*it;
gcz->update();
}
}
};
class laoban:public tongzhizhe
{
public:
virtual void Notify(){
cout << "我是老板" << endl;
tongzhizhe::Notify();
}
};
class mishu:public tongzhizhe
{
public:
virtual void Notify(){
cout << "我是秘书" << endl;
tongzhizhe::Notify();
}
};
int main(void)
{
tongzhizhe *t1 = new laoban();
tongzhizhe *t2 = new mishu();
xiaozhang *xz = new xiaozhang();
xiaowang *xw = new xiaowang();
t1->attach(xz);
t1->attach(xw);
t1->Notify();
t2->attach(xz);
t2->attach(xw);
t2->Notify();
return 0;
}
运行结果:
我是老板
小张收到
小王收到
我是秘书
小张收到
小王收到
二 观察者模式
我不是很喜欢这种命名,不够直观,不利于思路整理,初学还是guanchazhe,tongzhizhe这种看似很土,但是却比较容易理清思路。
观察者模式(Observer)结构图
在上面测试中,类tongzhizhe对应Subject.
类guanchazhe对应Observer.
类laoban和xiaowang对应ConcreteSubject
类mishu和xiaowang对应ConcreteObserver.
测试代码略
三 使用函数指针模拟委托功能探讨
看书上委托的定义
用C++来实现这两张图中的Update
1 .定义一个类叫EventHandler
2.在EventHandler中重载+运算中
3.定义个函数指针类型
4.在EventHandler定义一个链表。
聪明的你已经猜出该怎么做了吧
代码实现如下所示,写的时候发现对象的成员函数是不能直接赋值给指针的。
假设:xz.quchifan可以赋值给p1,那么p1()执行后,
cout << this->name << "去吃饭" << endl;
这条代码被执行,因为没有对象调用,所示this为空this->name 使用空指针调用,段错误
证明:非静态函数不能赋值给指针。
使用函数指针实现委托的计划破产。但是从中还是可以学习C++的函数指针,重载的灵活用法。
#include <iostream>
#include <list>
using namespace std;
typedef void (*update_pointer)(void);
class xiaozhang{
public:
string name;
void quchifan(void)//去吃饭
{
cout << this->name << "去吃饭" << endl;
}
};
class baoan
{
public:
static void quxunluo(void)//去巡逻
{
cout << "去巡逻" << endl;
}
};
class EventHandler{
public:
EventHandler(){
}
EventHandler& operator+(update_pointer p){
func_list.push_back(p);
return *this;
}
list<update_pointer> func_list;
void execute(){
list<update_pointer>::iterator it;
for(it = func_list.begin();it != func_list.end();it++){
(*it)();
}
}
};
class tongzhizhe{
public:
EventHandler update;
tongzhizhe(){
//update = new EventHandler();
}
};
int main(void)
{
tongzhizhe *t = new tongzhizhe();
xiaozhang xz;
//update_pointer p1 = (update_pointer)(xz.quchifan);
baoan ba;
t->update = (t->update) + (update_pointer)(ba.quxunluo);
t->update.execute();
return 0;
}
运行结果:
去巡逻