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