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; 
     }

  • 相关阅读:
    Parameter Binding in ASP.NET Web API
    Which HTTP methods match up to which CRUD methods?
    ErrorHandling in asp.net web api
    HttpStatusCode
    Autofac Getting Started(默认的构造函数注入)
    Autofac Controlling Scope and Lifetime
    luvit 被忽视的lua 高性能框架(仿nodejs)
    undefined与null的区别
    VsCode中使用Emmet神器快速编写HTML代码
    字符串匹配---KMP算法
  • 原文地址:https://www.cnblogs.com/blfshiye/p/3767245.html
Copyright © 2011-2022 走看看