设计模式一:关于C++写观察者模式的一些收获

先贴上部分代码:

#include "stdafx.h"
#include<iostream>
#include<string>
#include<vector>
using namespace std;
class Observer;
class Subject;
class Subject
{
public:
    Subject()
    {
        msg="orinal msg";
    }
    void add(Observer* ob)
    {
        vec.push_back(ob);
    }
    void show()
    {
        cout<<"broadcast:msg is:"<<msg<<endl;
    }
    void change(string msg)
    {
        this->msg=msg;
        notification();
    }
    void notification()
    {
        vector<Observer*>::iterator v = vec.begin();
         while( v != vec.end()) {
             (*v)->Showdate();
             v++;
      }
    }
    
private:
    vector<Observer*> vec;
    string msg; 

};
class Observer
{
public:
    Observer(Subject* sub)
    {
        this->sub=sub;
        this->sub->add(this);
    }
    void Showdate()
    {
        sub->show();
    }
private:
    Subject* sub;
};

说明一下:这么写编译会报错的!

 notification() 这一行报了错:
:错误 1 error C2027: 使用了未定义类型“Observer” 

:错误 2 error C2227: “->Showdate”的左边必须指向类/结构/联合/泛型类型

 

我刚写的时候也是很疑问,为什么会这样呢,经过一番研究,原来编译过不去的原因是因为,在notification()函数里面调用了Observer类里的方法showdate(),而这个方法的声明在notification()之后,所以编译器找不到.  

需要注意的一点是:虽然已经在开头声明了class Observer; class Subject;这两个类,但是 也仅仅是声明了类,并不代表声明了类里的函数。由于函数声明的位置不同 编译器仍有找不到的可能。

 

 

所以可以这么解决

 

#include "stdafx.h"
#include<iostream>
#include<string>
#include<vector>
using namespace std;
class Observer;
class Subject;
class Subject
{
public:
    Subject()
    {
        msg="orinal msg";
    }
    void add(Observer* ob)
    {
        vec.push_back(ob);
    }
    void show()
    {
        cout<<"broadcast:msg is:"<<msg<<endl;
    }
    void change(string msg)
    {
        this->msg=msg;
        notification();
    }
    void notification();
private:
    vector<Observer*> vec;
    string msg; 

};
class Observer
{
public:
    Observer(Subject* sub)
    {
        this->sub=sub;
        this->sub->add(this);
    }
    void Showdate()
    {
        sub->show();
    }
private:
    Subject* sub;
};
void Subject::notification()
{
        vector<Observer*>::iterator v = vec.begin();
         while( v != vec.end()) {
             (*v)->Showdate();
             v++;
      }
 }

可以看到,把notification这个方法声明到最后就可以了。

 

通过写这个观察者模式,我有些收获:

C++毕竟与JAVA不同,在JAVA里不会存在这些问题(不得不说JAVA在类和对象这个方面有很多东西做的确实比C++强上不少)

所以写C++时先定义类 再声明函数,尽量不要在类内就把函数写好。写的时候一定要注意:先声明的函数是否调用了后声明的函数。

 

PS:说下C++的this指针,this指针可以理解为指向这个对象本身的指针。

 

附上主函数:

int _tmain(int argc, _TCHAR* argv[])
{
    Subject* sub=new Subject();
    Observer* ob1=new Observer(sub);
    Observer* ob2=new Observer(sub);
    Observer* ob3=new Observer(sub);
   char opt;
while(true) { string tempmsg; cout<<"please input a number"<<endl; cin>>opt; switch(opt) { case '1': cout<<"please input the change msg"<<endl; cin>>tempmsg; sub->change(tempmsg); break; default: break; } } return 0; }

 

说下观察者模式的作用:

当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象:一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。

就拿我这个程序来说:可以把Subject看作一个水位监测,Observer看作显示水位状态的屏幕。 一旦监测(Subject)到水位发生变化 屏幕(Observer)立刻显示改变后的水位状态。

 

优点:

观察者和被观察者是一套触发机制:保证高度的协作;

缺点:

一个缺点:观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

 

以上只是我的愚见,如果有些地方有误欢迎批评指正 oO(AIA)Oo

posted on 2017-05-05 19:08  yrsss  阅读(330)  评论(0编辑  收藏  举报