设计模式: 观察者模式

来源:互联网 发布:焦娇淘宝主播 编辑:程序博客网 时间:2024/06/10 08:42

下面是观察者模式的一个例子,源代码来自《设计模式精解-Gof 23种设计模式解析附C++实现源码》。

源代码在每个观察者对象析构时有bug,会导致重复删除subject对象。


//Subject.h#ifndef  SUBJECT_H#define  SUBJECT_H#include <list>#include <string>using namespace std;typedef string State;class Observer;class Subject{public:virtual ~Subject();virtual void Attach(Observer* obv);// 注册virtual void Detach(Observer* obv);// 注销virtual void Notify();virtual void SetState(const State& st) = 0;virtual State GetState() = 0;protected:Subject();// constructor is protected? Subject是抽象类private:list<Observer*> *_obvs;//存放的是指针,又称发布-订阅(publish-subscribe)};class ConcreteSubject: public Subject{public:ConcreteSubject();~ConcreteSubject();State GetState();void SetState(const State& st);protected:private:State _st;};#endif//~SUBJECT_H


Subject.cpp 

#include "Subject.h"#include "Observer.h"#include <iostream>#include <list>using namespace std;typedef string state;Subject::Subject(){ //在模板的使用之前一定要new,创建_obvs = new list<Observer*>;}Subject::~Subject(){//使用完后释放列表        delete _obvs;        _obvs = NULL;}void Subject::Attach(Observer* obv){_obvs->push_front(obv);}void Subject::Detach(Observer* obv){if (obv != NULL)_obvs->remove(obv);}void Subject::Notify(){list<Observer*>::iterator it;for (it = _obvs->begin();it != _obvs->end();it++){ //关于模板和iterator的用法(*it)->Update(this);}}ConcreteSubject::ConcreteSubject(){_st = '\0';}ConcreteSubject::~ConcreteSubject(){ }State ConcreteSubject::GetState(){return _st;}void ConcreteSubject::SetState(const State& st){         _st = st;}


Observer.h 

#ifndef OBSERVER_H#define OBSERVER_H#include "Subject.h"#include <string>using namespace std;typedef string State;class Observer{public:virtual ~Observer();virtual void Update(Subject* sub) = 0;virtual void PrintInfo() = 0;protected:Observer();State _st;private:};class ConcreteObserverA:public Observer{public:ConcreteObserverA(Subject* sub);virtual ~ConcreteObserverA();virtual Subject* GetSubject();//传入Subject作为参数,这样可以让一个View属于多个的Subject。void Update(Subject* sub);void PrintInfo();protected:private:Subject* _sub;};class ConcreteObserverB:public Observer{public:ConcreteObserverB(Subject* sub);virtual ~ConcreteObserverB();virtual Subject* GetSubject();//传入Subject作为参数,这样可以让一个View属于多个的Subject。void Update(Subject* sub);void PrintInfo();protected:private:Subject* _sub;};#endif //~OBSERVER_H


Observer.cpp

#include "Observer.h"#include "Subject.h"#include <iostream>#include <string>using namespace std;Observer::Observer(){_st = '\0';//字符串的结尾标志}Observer::~Observer(){}ConcreteObserverA::ConcreteObserverA(Subject* sub){_sub = sub;_sub->Attach(this);//注册}ConcreteObserverA::~ConcreteObserverA(){_sub->Detach(this);//注销//if (_sub != 0)//delete _sub;}Subject* ConcreteObserverA::GetSubject(){return _sub;}void ConcreteObserverA::PrintInfo(){cout<<"ConcreteObserverA observer.... "<<_sub->GetState()<<endl;}void ConcreteObserverA::Update(Subject* sub){_st = sub->GetState();PrintInfo();}ConcreteObserverB::ConcreteObserverB(Subject* sub){_sub = sub;_sub->Attach(this);}ConcreteObserverB::~ConcreteObserverB(){_sub->Detach(this);//if (_sub != 0)//{//delete _sub;//}}Subject* ConcreteObserverB::GetSubject(){return _sub;}void ConcreteObserverB::PrintInfo(){cout<<"ConcreteObserverB observer.... "<<_sub->GetState()<<endl;}void ConcreteObserverB::Update(Subject* sub){_st = sub->GetState();PrintInfo();}

main.cpp
//main.cpp#include "Subject.h"#include "Observer.h"#include <iostream>using namespace std;int main(int argc, char* argv[]){ConcreteSubject* sub = new ConcreteSubject();Observer* o1 = new ConcreteObserverA(sub);Observer* o2 = new ConcreteObserverB(sub);sub->SetState("old");sub->Notify();sub->SetState("new"); //也可以由Observer调用sub->Notify();delete o2;o2 = NULL;delete o1;o1 = NULL;delete sub;sub =NULL;system("pause");return 0;}

0 0
原创粉丝点击