必做作业3:观察者模式解析

什么是观察者模式

建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应做出反应。在此,发生改变的对象称为观察目标,而被通知的对象称为观察者,一个观察目标可以对应多个观察者,而且这些观察者之间没有相互联系,可以根据需要增加和删除观察者,使得系统更易于扩展。

模式结构

观察者模式包含如下角色:

Subject: 目标

ConcreteSubject: 具体目标

Observer: 观察者

ConcreteObserver: 具体观察者

代码分析

目标类

源码链接:

https://github.com/me115/design_patterns/blob/master/code/Obeserver/Subject.h#L15

https://github.com/me115/design_patterns/blob/master/code/Obeserver/Subject.cpp#L18

 1 class Subject
 2 {
 3 
 4 public:
 5     Subject();
 6     virtual ~Subject();
 7     Obeserver *m_Obeserver;
 8 
 9     void attach(Obeserver * pObeserver);
10     void detach(Obeserver * pObeserver);
11     void notify();
12         
13     virtual int getState() = 0;
14     virtual void setState(int i)= 0;
15     
16 private:
17     vector<Obeserver*> m_vtObj;
18 
19 };
20 
21 void Subject::attach(Obeserver * pObeserver){
22     m_vtObj.push_back(pObeserver);
23 }
24 
25 void Subject::detach(Obeserver * pObeserver){
26     for(vector<Obeserver*>::iterator itr = m_vtObj.begin();
27         itr != m_vtObj.end(); itr++)
28     {
29         if(*itr == pObeserver)
30         {
31             m_vtObj.erase(itr);
32             return;
33         }            
34     }
35 }
36 
37 void Subject::notify(){
38     for(vector<Obeserver*>::iterator itr = m_vtObj.begin();
39         itr != m_vtObj.end();
40          itr++)
41     {    
42         (*itr)->update(this);        
43     }
44 }

分析:

目标类为纯虚类,自身有一个有观察者指针组成的数组,记录正在观察当前目标的观察者。目标类还有有attach()、dettach()和notify()方法,分别为增加观察者、删除观察者和通知观察者。

具体目标类

源码链接:

https://github.com/me115/design_patterns/blob/master/code/Obeserver/ConcreteSubject.h#L13

https://github.com/me115/design_patterns/blob/master/code/Obeserver/ConcreteSubject.cpp#L20

 1 class ConcreteSubject : public Subject
 2 {
 3 
 4 public:
 5     ConcreteSubject();
 6     virtual ~ConcreteSubject();
 7 
 8     virtual int getState();
 9     virtual void setState(int i);
10 
11 private:
12     int m_nState;
13 
14 };
15 
16 int ConcreteSubject::getState(){
17     return m_nState;
18 }
19 
20 
21 void ConcreteSubject::setState(int i){
22     m_nState = i;
23 }

分析:

具体目标类继承至目标类,自身有指示当前状态的成员变量m_nState,并具体实现了getState()方法和setState()方法。

观察者类

源码链接:

https://github.com/me115/design_patterns/blob/master/code/Obeserver/Obeserver.h#L13

https://github.com/me115/design_patterns/blob/master/code/Obeserver/Obeserver.cpp#L10

 1 class Obeserver
 2 {
 3 public:
 4     Obeserver();
 5     virtual ~Obeserver();
 6     virtual void update(Subject * sub) = 0;
 7 };
 8 
 9 Obeserver::Obeserver(){
10 }
11 
12 Obeserver::~Obeserver(){
13 }

分析:

观察者类也是纯虚类,有一个可以被外界调用的update()方法。

具体观察者类

源码链接:

https://github.com/me115/design_patterns/blob/master/code/Obeserver/ConcreteObeserver.h#L14

https://github.com/me115/design_patterns/blob/master/code/Obeserver/ConcreteObeserver.cpp#L14

 1 class ConcreteObeserver : public Obeserver
 2 {
 3 
 4 public:
 5     ConcreteObeserver(string name);
 6     virtual ~ConcreteObeserver();
 7     virtual void update(Subject * sub);
 8 
 9 private:
10     string m_objName;
11     int m_obeserverState;
12 };
13 
14 ConcreteObeserver::ConcreteObeserver(string name){
15     m_objName = name;
16 }
17 
18 ConcreteObeserver::~ConcreteObeserver(){
19 
20 }
21 
22 void ConcreteObeserver::update(Subject * sub){
23     m_obeserverState = sub->getState();
24     cout << "update oberserver[" << m_objName << "] state:" << m_obeserverState << endl;
25 }

分析:

具体观察者类继承至观察者类,自身有成员变量名称objName和状态m_obeserverState,并且具体实现了update()方法。

示例

源码链接:

https://github.com/me115/design_patterns/blob/master/code/Obeserver/main.cpp#L9

 1 int main(int argc, char *argv[])
 2 {
 3     Subject * subject = new ConcreteSubject();
 4     Obeserver * objA = new ConcreteObeserver("A");
 5     Obeserver * objB = new ConcreteObeserver("B");
 6     subject->attach(objA);
 7     subject->attach(objB);
 8     
 9     subject->setState(1);
10     subject->notify();
11     
12     cout << "--------------------" << endl;
13     subject->detach(objB);
14     subject->setState(2);
15     subject->notify();
16     
17     delete subject;
18     delete objA;
19     delete objB;
20         
21     return 0;
22 }

分析:

例子中实例了两个观察者,一个目标,并将观察者的指针添加到目标的观察者数组中。目标更改状态后,通过调用notify()方法通知所有的观察者自身状态的改变。然后将观察者B取消对目标的观察,再次目标状态后观察者B便不会收到目标的状态改变。

posted @ 2018-10-25 17:09  Farrell_Meng  阅读(246)  评论(0)    收藏  举报