// 观察者(Observer )模式又名发布-订阅(Publish/Subscribe)模式。GOF 给观察者模
//式如下定义:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依
//赖于它的对象都得到通知并被自动更新。
//观察者模式的起源我觉得 应该是在 GUI 和业务数据的处理上
//观察者模式的组成部分。
//1) 抽象目标角色(Subject ):目标角色知道它的观察者,可以有任意多个观察者观察同一
// 个目标。并且提供注册和删除观察者对象的接口。目标角色往往由抽象类或者接口来实
// 现。
//2) 抽象观察者角色(Observer ):为那些在目标发生改变时需要获得通知的对象定义一个
// 更新接口。抽象观察者角色主要由抽象类或者接口来实现。
//3) 具体目标角色(Concrete Subject ):将有关状态存入各个Concrete Observer 对象。当
// 它的状态发生改变时, 向它的各个观察者发出通知。
//4) 具体观察者角色(Concrete Observer ):存储有关状态,这些状态应与目标的状态保持
// 一致。实现Observer 的更新接口以使自身状态与目标的状态保持一致。在本角色内也
// 可以维护一个指向Concrete Subject 对象的引用。
// 放上观察者模式的类图,这样能将关系清晰的表达出来。
//
//使用情况
// GOF 给出了以下使用观察者模式的情况:
// 1) 当一个抽象模型有两个方面, 其中一个方面依赖于另一方面。将这二者封装在独立
// 的对象中以使它们可以各自独立地改变和复用。
// 2) 当对一个对象的改变需要同时改变其它对象, 而不知道具体有多少对象有待改变。
// 3) 当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之, 你不希望
// 这些对象是紧密耦合的。
#include <list>
#include <string>
//Observer模式,就是建立一种机制,使多个对象依赖于某个特定对象,当这个特定的对象改变时,能通知到依赖它的所有对象作出反应。
//类A(观察目标)中包含一个 节点为观察类的链表 包含一个通知状态函数 。 具体化类A可以修改状态 状态变更后调用通知观察者调用自身的update做出反馈using namespace std;
typedef string State; //与宏类似
class Observer;class Subject //观察目标对象
{
public:
virtual ~Subject();
//添加 删除观察者
virtual void Attach(Observer* obv) {_obvs->push_front(obv);}//贴上 系 附上
virtual void Detach(Observer* obv){if (obv != NULL) _obvs->remove(obv);}//拆卸, 使分开, 使分离 //通知观察者
virtual void Notify()//通知
{
list<Observer*>::iterator it;
it = _obvs->begin();
for (;it != _obvs->end();it++)
{ //关于模板和iterator的用法
(*it)->Update(this); //更新对目标的观察结果
}
}
virtual void SetState(const State& st) = 0;
virtual State GetState() = 0;
protected:
Subject()
{ //****在模板的使用之前一定要new,创建
_obvs = new list<Observer*>;
}
private:
list<Observer* >* _obvs;
};class ConcreteSubject:public Subject
{
public:
ConcreteSubject(){_st = '\0';}
~ConcreteSubject(); State GetState(){return _st;}
void SetState(const State& st){_st = st;}
protected:
private:
State _st;
};class Observer
{
public:
virtual ~Observer(){_st = '\0';}
virtual void Update(Subject* sub) = 0;
virtual void PrintInfo() = 0;//反馈观察结果
protected:
Observer();
State _st; //用来记录观察的到的状态
private:
};class ConcreteObserverA:public Observer
{
public:
virtual Subject* GetSubject(){return _sub;}//得到观察目标
ConcreteObserverA(Subject* sub)
{
_sub = sub;
_sub->Attach(this);
} virtual ~ConcreteObserverA()
{
_sub->Detach(this);
if (_sub != 0)
delete _sub;
}
//传入Subject作为参数,这样可以让一个View属于多个的Subject。
void Update(Subject* sub)
{
_st = sub->GetState();
PrintInfo();
} void PrintInfo()
{
cout<<"ConcreteObserverA observer.... "<<_sub->GetState()<<endl;
}
protected:
private:
Subject* _sub;
};class ConcreteObserverB:public Observer
{
public:
virtual Subject* GetSubject(){return _sub;}
ConcreteObserverB(Subject* sub)
{
_sub = sub;
_sub->Attach(this);
} virtual ~ConcreteObserverB()
{
_sub->Detach(this);
if (_sub != 0)
delete _sub;
}
//传入Subject作为参数,这样可以让一个View属于多个的Subject。
void Update(Subject* sub)
{
_st = sub->GetState();
PrintInfo();
}
void PrintInfo()
{
cout<<"ConcreteObserverB observer.... "<<_sub->GetState()<<endl;
}
protected:
private:
Subject* _sub;
};void Observe_test()
{
ConcreteSubject* sub = new ConcreteSubject();//创建观察目标 Observer* o1 = new ConcreteObserverA(sub);//创建一个以sub为观察目标的观察者
Observer* o2 = new ConcreteObserverB(sub);
sub->SetState("old");//每次状态改变时 目标对象都会通知观察者
sub->Notify();
sub->SetState("new");
sub->Notify();
;
}