Observer

来源:互联网 发布:全民淘宝客助手官网 编辑:程序博客网 时间:2024/06/05 19:26

// 观察者(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();
;
}