zoukankan      html  css  js  c++  java
  • 学习设计模式--观察者模式(C++)

    1. 说说简单的函数回调

    首先说说一种简单的函数回调机制(一种通过获取对象的指针来进行函数的调用方法)以下是代码演示---

    这是观察者(被回调)部分:

    class Observer
    {
    public:
    	// 抽象观察者的纯虚函数
    	virtual void UpdateMessage() = 0;
    };
    
    class ConcreteObserver : public Observer
    {
    public:
    	// 实现抽象类的纯虚函数
    	void UpdateMessage();
    }
    
    void ConcreteObserver::UpdateMessage()
    {
    	// 这里实现详细的操作
    }
    
    class Subject
    {
    public:
    	Subject(Observer* observer = NULL);
    	
    	void OnMessageChanged();
    	
    private:
    	Observer* m_observer;
    };
    

    以下是被观察者(主动调用)部分:

    Subject::Subject(Observer* observer)
    {
    	// 将Observer的对象指针传进来并复制
    	m_observer = observer;
    }
    
    void Subject::OnMessageChanged()
    {
    	if(m_observer)
    	{
    		// 通过多态机制下的指针回调观察者的函数
    		m_observer->UpdateMessage();
    	}
    }

    如上所看到的,程序中的一个对象通过获取还有一个对象的指针,来进行函数的调用。这不是类之间的直接调用,仅仅因该对象指针是在多态下定义的。

    进一步拓展,假设有一个或多个多个观察者来关注一个或多个对象,那么就能够用通常所说的观察者模式来实现了。


    2. 观察者模式的应用场合和特点

    观察者模式一般出如今这种场合:存在观察者和被观察对象。详细样例,比方订阅邮件或杂志, 微博关注某某主题等。当你在微博上关注了某个主题后,当这个主题有新的信息发出来时,你的微博主页将会对应收到它的更新信息。

    而观察者模式提供了这种一个对象模型,使得对象们(主题和观察者)之间松耦合:

    (1)观察者的更替或数据模块的更新不会影响主题的存在。

    (2)观察者和主题类能够方便的独立地被程序其它模块使用。

    (3)一个主题能够注冊多个观察者,也能够动态删除观察者; 一个观察者也能够注冊多个主题,也能够撤销注冊。

         比如一份天气预报能够被多个用户订阅,当数据更新时会通知全部注冊的用户。一个用户也能够订阅多份天气预报,广州的,珠海的等等。


    3.简单的代码演示

    (1)演示的功能能够用这个类图来表达,类图中定义了Subject和Observer两个接口,并定义了两个详细主题类和三个详细观察者类。


    (2)详细代码实现

    首先是主题类,分别定义了类ConcreteSubjectA和类ConcreteSubjectB。

    class Subject
     { 
     public: 
         virtual void registerObserver(shared_ptr<Observer> observer) = 0; 
         virtual void removeObserver(shared_ptr<Observer> observer) = 0; 
         virtual void notifyObserver() = 0; 
     };
     
     class ConcreteSubjectA : public Subject
     { 
     public: 
          ConcreteSubjectA() 
         { 
    	     // do something here
    		 testValue = 1;
         }
     
         void registerObserver(shared_ptr<Observer> observer) 
         { 
             observersList.push_back(observer); 
         } 
         void removeObserver(shared_ptr<Observer> observer) 
         { 
             observersList.remove(observer); 
         }
     
         void notifyObserver() 
         { 
             for (list<shared_ptr<Observer> >::iterator it = observersList.begin(); 
                 it != observersList.end(); ++it) 
             { 
                 (*it)->updateData(testValue); 
             } 
         }
     
     private: 
         list<shared_ptr<Observer> > observersList; 
    	 int testValue;
     };
     
     class ConcreteSubjectB : public Subject
     { 
     public: 
          ConcreteSubjectB() 
         { 
    	     // do something here
    		 testValue = 2;
         }
     
         void registerObserver(shared_ptr<Observer> observer) 
         { 
             observersList.push_back(observer); 
         } 
         void removeObserver(shared_ptr<Observer> observer) 
         { 
             observersList.remove(observer); 
         }
     
         void notifyObserver() 
         { 
             for (list<shared_ptr<Observer> >::iterator it = observersList.begin(); 
                 it != observersList.end(); ++it) 
             { 
                 (*it)->updateData(testValue); 
             } 
         }
     
     private: 
         list<shared_ptr<Observer> > observersList; 
    	 int testValue;
     };
    接着是观察者类,分别定义了类ConcreteObserverA,类ConcreteObserveB,类ConcreteObserverC。

    class Observer 
     { 
     public: 
         virtual void updateData(int val) = 0; 
     };
     
     class ConcreteObserverA : public Observer 
     { 
     public: 
         void updateData(int val) 
         { 
    		// do something here
             cout << "In A :" << val <<endl; 
         } 
     };
     
     class ConcreteObserverB : public Observer 
     { 
     public: 
         void updateData(int val) 
         { 
    		// do something here
             cout << "In B :" << val <<endl; 
         } 
     };
     
     class ConcreteObserverC : public Observer 
     { 
     public:
         void updateData(int val) 
         { 
    		// do something here
             cout << "In C :" <<val <<endl; 
         } 
     };

    然后,我们能够这样使用他们:

     int main() 
     { 
         shared_ptr<Subject> subjectA(new ConcreteSubjectA()); 
         shared_ptr<Subject> subjectB(new ConcreteSubjectB()); 
    	 
         shared_ptr<Observer> observerA(new ConcreteObserverA()); 
         shared_ptr<Observer> observerB(new ConcreteObserverB()); 
         shared_ptr<Observer> observerC(new ConcreteObserverC()); 
    
         subjectA->registerObserver(observerA); 
         subjectA->registerObserver(observerB); 
         subjectB->registerObserver(observerC); 
    	 
    	 // 主题A有更新时将通知观察者A,B
         subjectA->notifyObserver();
    	 // 主题B有更新时将通知观察者C
    	 subjectB->notifyObserver();
     
         return 0; 
     }

  • 相关阅读:
    滴滴快车奖励政策,高峰奖励,翻倍奖励,按成交率,指派单数分级(4月19日)
    2016年小升初海淀区全部初中排名分析
    LVM Linear vs Striped Logical Volumes
    Spring Data Redis实现消息队列——发布/订阅模式
    Redis Pubsub命令用法
    mysql 截取身份证出生日期
    MA均线组合
    Eclipse代码格式化规范
    JSON Web Token实际应用
    JSON Web Token单点登录设计
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/3842064.html
Copyright © 2011-2022 走看看