`
duoerbasilu
  • 浏览: 1483927 次
文章分类
社区版块
存档分类
最新评论

学习设计模式--观察者模式(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; 
 }

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics