设计模式之观察者模式C++实现

优点: 1、观察者和被观察者是抽象耦合的。 2、建立一套触发机制。

缺点: 1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。 2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。 3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

使用场景:

  • 一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
  • 一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
  • 一个对象必须通知其他对象,而并不知道这些对象是谁。
  • 需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。

大话设计模式上的例子,自己写了一遍:

  1 #include<iostream>
  2 #include<list>
  3 #include<string>
  4 using namespace std;
  5 
  6 class Subject;
  7 
  8 class Observer{     //观察者抽象类
  9     protected:
 10     string name;    //观察者自己的名字
 11     Subject* sub;   //观察的对象
 12     
 13     public:
 14     Observer(const string&,Subject*);
 15     virtual void Update()=0;
 16 };
 17 
 18 class StockObserver:public Observer{    //炒股的观察者类
 19     private:
 20 
 21     public:
 22     StockObserver(const string& _name,Subject* _sub):Observer(_name,_sub){} //委托Observer类的构造函数进行构造
 23     void Update();
 24 };
 25 
 26 class NbaObserver:public Observer{      //看NBA的观察者类
 27     private:
 28 
 29     public:
 30     NbaObserver(const string& _name,Subject* _sub):Observer(_name,_sub){} //委托Observer类的构造函数进行构造
 31     void Update();
 32 };
 33 
 34 
 35 class Subject{  //通知者抽象基类
 36     protected:
 37     list<Observer*> observerList;   //一个集合,存储所有观察本对象的观察者对象
 38 
 39     public:
 40     string status;      //本对象的状态
 41     virtual void attach(Observer*)=0;       //新增一个观察者
 42     virtual void detach(Observer*)=0;       //减少一个观察者
 43     virtual void Notify()=0;                //通知所有观察者
 44 };
 45 
 46 Observer::Observer(const string& _name,Subject* _sub):name(_name),sub(_sub){
 47     _sub->attach(this);
 48 }//构造函数
 49 
 50 void StockObserver::Update(){
 51     cout<<name<<" get information: "<<sub->status<<endl;
 52     cout<<"Close the stock and i'm working!"<<endl<<endl;
 53 }
 54 
 55 void NbaObserver::Update(){
 56     cout<<name<<" get information: "<<sub->status<<endl;
 57     cout<<"Close the NBA and i'm working!"<<endl<<endl;
 58 }
 59 
 60 class BossSubject:public Subject{  //老板通知者类
 61     private:
 62 
 63     public:
 64     BossSubject(){status="Boss come!";}
 65     void attach(Observer* _observer){
 66         observerList.push_back(_observer);
 67     }
 68     void detach(Observer* _observer){
 69         observerList.remove(_observer);
 70     }
 71     void Notify(){
 72         for(const auto& obs:observerList){
 73             obs->Update();
 74         }
 75     }
 76 };
 77 
 78 class SecretarySubject:public Subject{     //秘书通知者类
 79     private:
 80 
 81     public:
 82     SecretarySubject(){status="Secretary come!";}
 83     void attach(Observer* _observer){
 84         observerList.push_back(_observer);
 85     }
 86     void detach(Observer* _observer){
 87         observerList.remove(_observer);
 88     }
 89     void Notify(){
 90         for(const auto& obs:observerList){
 91             obs->Update();
 92         }
 93     }
 94 };
 95 
 96 int main(){
 97     BossSubject* boss=new BossSubject();    //老板
 98     SecretarySubject* secretary=new SecretarySubject();     //秘书
 99     StockObserver* stockA=new StockObserver("stockA",boss);
100     StockObserver* stockB=new StockObserver("stockB",boss);
101 
102 
103     NbaObserver* nba1=new NbaObserver("nba1",secretary);
104     NbaObserver* nba2=new NbaObserver("nba2",secretary);
105 
106     boss->Notify();
107     secretary->Notify();
108     cout<<"-------------------------------"<<endl;
109     cout<<"boss detach stockB and secretary detach nba1!"<<endl<<"-------------------------------"<<endl;
110     boss->detach(stockB);
111     secretary->detach(nba1);
112 
113     boss->Notify();
114     secretary->Notify();
115     getchar();
116 }

结果:

猜你喜欢

转载自www.cnblogs.com/FdWzy/p/12680622.html
今日推荐