设计模式之观察者模式,C++实现(上部分)
原文地址: http://blog.csdn.net/iuhsihsow
说起观察者模式犹如黄河之水,滔滔不绝,一发而不可收拾啊。
今天先写上半部分,明天写事件委托。
直接上代码,感谢scl的分享
// 观察者模式定义了一种一对多的依赖,让多个观察者对象同时监听某一个 // 主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使 // 他们能够自动更新自己。 // 观察者模式是一个很重要的模式,使用频率是非常高啊 // 当一个对象改变需要同时改变其他对象的时候 // 当具体不知道有多少个对象有待改变的时候。 // 适用的范围 // 在《大话模式》中,众多的观察者对象是上班开小差,看NBA,炒股票的同事 // 主题对象是坐在门口的前台。当老板回到公司的时候,前台会通知所有的“注册” // 后的同事赶紧干正经事。 // 其实三维浏览中也可以用到 // 将各种行为作为观察者对象,摄像机为主题对象,主题对象通过给观察对象当前的 // 时间来更新各种浏览控制器,浏览控制器再调整摄像机各个参数。 // 情景假设 // 对一飞机飞行进行控制, // 先飞行小于10秒 // 在旋转小于20秒 #include "stdafx.h" #include <Windows.h> #include <iostream> #include <vector> // 毕竟作为示例,还是开发效率重要, // 所以就用using namespace吧 using namespace std; //浏览控制器基类 class IControl { public: virtual bool Update(double dtime) = 0; virtual bool Begin(double dtime ) = 0; virtual bool IsFinish() = 0; protected: doublem_dLastTime; boolm_bFinish; private: }; //飞行浏览控制器 class FlyControl : public IControl { public: bool Begin(double dtime) { m_bFinish = false; m_dLastTime = dtime; return true; } bool Update(double dtime) { double dDetal = dtime - m_dLastTime; if (dDetal > 10) { cout<<"Complete fly!"<<endl; m_bFinish = true; return true; } cout<<"We have fly "<<dDetal<<" meters!"<<endl; } bool IsFinish() { return m_bFinish; } protected: private: }; //转向浏览控制器 class RotateControl : public IControl { public: bool Begin(double dtime) { m_bFinish = false; m_dLastTime = dtime; return true; } bool Update(double dtime) { double dDetal = dtime - m_dLastTime; if (dDetal > 20) { cout<<"Complete Rotate!"<<endl; m_bFinish = true; return true; } cout<<"We have Rotate "<<dDetal<<" degress"<<endl; } bool IsFinish() { return m_bFinish; } protected: private: }; // 控制器集合 class ControlList { public: int GetCount() { return m_CtrlVec.size(); } void SetTime(double dTime) { m_dLastTime = dTime; } void Attach(IControl *pCtrl) { for (int i = 0; i < m_CtrlVec.size(); i++) { if (pCtrl == m_CtrlVec[i]) { return; } } m_CtrlVec.push_back(pCtrl); } void Detach(IControl *pCtrl) { for (int i = 0; i < m_CtrlVec.size(); i ++) { if (pCtrl == m_CtrlVec[i]) { m_CtrlVec.erase(m_CtrlVec.begin() + i); } return; } } bool UpdateAllCtrls(double dtime) { double dT = dtime - m_dLastTime; if (dT == 0.0) { return false; } int nSize = m_CtrlVec.size(); if ( m_CtrlVec.size() != 0 ) { IControl* pCtrl = m_CtrlVec.front(); if ( NULL != pCtrl ) { pCtrl->Update( dtime ); if ( pCtrl->IsFinish() ) { delete pCtrl; pCtrl = NULL; m_CtrlVec.erase(m_CtrlVec.begin()); if ( m_CtrlVec.size() != 0 ) { pCtrl = m_CtrlVec.front(); if ( NULL != pCtrl ) { pCtrl->Begin( dtime ); } } } } } m_dLastTime = dtime; return true; } protected: private: std::vector<IControl*>m_CtrlVec; doublem_dLastTime; }; // // Plain // 飞机类 class Plain : public ControlList { public: protected: private: }; int _tmain(int argc, _TCHAR* argv[]) { //演示程序,就不用多线程了 Plain plain; //恩,现在时刻是0.0 double curTime = 0.0; plain.SetTime(curTime); FlyControl *pFlyCtrl = new FlyControl; pFlyCtrl->Begin(curTime); plain.Attach(pFlyCtrl); //恩,现在时刻是0.1 curTime = 0.1; RotateControl *pRoCtrl = new RotateControl; pRoCtrl->Begin(curTime); plain.Attach(pRoCtrl); while(plain.GetCount()) { Sleep(200); // 模拟时间的流逝 // 7.5倍的速度 curTime += 1.5; plain.UpdateAllCtrls(curTime); } return 0; } // 输出结果 //We have fly 1.6 meters! //We have fly 3.1 meters! //We have fly 4.6 meters! //We have fly 6.1 meters! //We have fly 7.6 meters! //We have fly 9.1 meters! //Complete fly! //We have Rotate 1.5 degress //We have Rotate 3 degress //We have Rotate 4.5 degress //We have Rotate 6 degress //We have Rotate 7.5 degress //We have Rotate 9 degress //We have Rotate 10.5 degress //We have Rotate 12 degress //We have Rotate 13.5 degress //We have Rotate 15 degress //We have Rotate 16.5 degress //We have Rotate 18 degress //We have Rotate 19.5 degress //Complete Rotate! //请按任意键继续. . .