设计模式详解
观察者模式
观察者模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都要得到通知并自动更新。
观察者模式从根本上讲必须包含两个角色:观察者和被观察对象。
-
被观察对象自身应该包含一个容器来存放观察者对象,当被观察者自身发生改变时通知容器内所有的观察者对象自动更新。
-
观察者对象可以注册到被观察者的中,完成注册后可以检测被观察者的变化,接收被观察者的通知。当然观察者也可以被注销掉,停止对被观察者的监控。
#include <bits/stdc++.h>
using namespace std;
class View;
class DataModel //数据模型
{
public:
virtual ~DataModel(){}
virtual void addView(View* view) = 0; //纯虚函数
virtual void removeView(View* view)=0;
virtual void notify()=0; //通知函数
};
class View //视图
{
public:
virtual ~View(){cout<<"~View()"<<endl;}
virtual void update()=0;
virtual void setViewName(const string& name)=0;
virtual const string& name()=0;
};
//具体被观察类
class IntDataModel:public DataModel
{
public:
virtual ~IntDataModel()
{
m_pViewList.clear();
}
virtual void addView(View* view)
{
View* temp(view);
list<View*>::iterator it = find(m_pViewList.begin(), m_pViewList.end(), temp);
if(it==m_pViewList.end())
{
m_pViewList.push_front(temp);
}
else
cout<<"View already exists"<<endl;
}
virtual void removeView(View* view)
{
list<View*>::iterator it = m_pViewList.begin();
for(; it!=m_pViewList.end();it++)
{
if((*it)==view)
{
m_pViewList.erase(it);
cout<<"remove view"<<endl;
return;
}
}
}
virtual void notify()
{
list<View*>::iterator it = m_pViewList.begin();
for(;it!=m_pViewList.end();it++)
{
View* temp = *it;
temp->update();
}
}
private:
list<View*> m_pViewList;
};
class TableView:public View
{
public:
TableView():m_name("unKnown"){}
TableView(const string& name):m_name(name){}
~TableView(){cout<<"~TableView()"<<m_name.data()<<endl;}
void update(){cout<<m_name.data()<<"updata"<<endl;}
void setViewName(const string& name)
{
m_name = name;
}
const string& name()
{
return m_name;
}
private:
string m_name;
};
int main()
{
TableView* v1 = new TableView("TableView1");
TableView* v2 = new TableView("TableView2");
TableView* v3 = new TableView("TableView3");
TableView* v4 = new TableView("TableView4");
IntDataModel* model = new IntDataModel;
model->addView(v1);
model->addView(v2);
model->addView(v3);
model->addView(v4);
model->notify();
cout<<"------------\n"<<endl;
model->removeView(v2);
model->notify();
delete model;
model = NULL;
return 0;
}