我与C++设计模式(十五)——观察者模式

毋庸置疑,observer模式的地位是十分重要的,此处省略一些套话,那么什么是observer模式,他在帮我们解决什么问题或者说他在面对什么情形进行设计的。

observer模式要解决的问题是,建立一个一对多的依赖关系,并且做到当“一”变化的时候,“多”能够及时作出相应的响应,书中举的例子很好,即,对一组数据进行统计分析,我们希望可以用多种形式进行展现,有表格,柱状图,百分比图,或者变化曲线等,当数据发生改变时(说不定我们正在说的数据正是股票的指数呢?),各种展现形式也应该做出反应。这就是观察者模式。


#ifndef _SUBJECT_H__
#define _SUBJECT_H__

#include <list>
#include <string>
using namespace std;

class observer;
typedef string state;

class subject
{
public:
	virtual ~subject();
	virtual void attach(observer *p_obs);
	virtual void detach(observer *p_obs);
	virtual void notify();
	virtual void set_state(const state&) = 0;
	virtual state get_state() = 0;

protected:
	subject();

private:
	list<observer *> *_pl_obs;
};

class concrete_subject:public subject
{
public:
	concrete_subject();
	~concrete_subject();
	state get_state();
	void set_state(const state&);

private:
	state _st;
};

#endif

//subject.cpp

#include "subject.h"
#include "observer.h"

subject::subject()
:_pl_obs(new list<observer *>)
{
}

subject::~subject()
{
}

void subject::attach(observer *p_obs)
{
	_pl_obs->push_front(p_obs);
}

void subject::detach(observer *p_obs)
{
	if (p_obs)
		_pl_obs->remove(p_obs);
}

void subject::notify()
{
	list<observer *>::iterator ite = _pl_obs->begin();
	for ( ; ite != _pl_obs->end(); ++ite)
	{
		(*ite)->update(this);
	}
}


concrete_subject::concrete_subject()
{
}

concrete_subject::~concrete_subject()
{
}

state concrete_subject::get_state()
{
	return _st;
}

void concrete_subject::set_state(const state &st)
{
	_st = st;
}

#ifndef _OBSERVER_H__
#define _OBSERVER_H__

#include <string>
using namespace std;

class subject;
typedef string state;

class observer
{
public:
	~observer();
	virtual void update(subject *) = 0;
	virtual void print_info() = 0;

protected:
	observer();
	state _st;
};

class concrete_observer_A:public observer
{
public:
	concrete_observer_A(subject *);
	~concrete_observer_A();

	virtual subject *get_subject();
	void update(subject *);
	void print_info();

private:
	subject *_p_sub;
};

class concrete_observer_B:public observer
{
public:
	concrete_observer_B(subject *);
	~concrete_observer_B();

	virtual subject *get_subject();
	void update(subject *);
	void print_info();

private:
	subject *_p_sub;
};
#endif

//observer.cpp

#include "observer.h"
#include "subject.h"
#include <iostream>
using namespace std;

observer::observer()
{
}

observer::~observer()
{
}

//-----------------A------------------
concrete_observer_A::concrete_observer_A(subject *p_sub)
:_p_sub(p_sub)
{
	_p_sub->attach(this);
}

concrete_observer_A::~concrete_observer_A()
{
	_p_sub->detach(this);
	if (_p_sub)
	{
		delete _p_sub;
		_p_sub = NULL;
	}
}

void concrete_observer_A::update(subject * p_sub)
{
	_st = _p_sub->get_state();
	print_info();
}

subject *concrete_observer_A::get_subject()
{
	return _p_sub;
}

void concrete_observer_A::print_info()
{
	cout<<"concrete_observer_A observer..."<<_p_sub->get_state()<<endl;
}


//-----------------B------------------
concrete_observer_B::concrete_observer_B(subject *p_sub)
:_p_sub(p_sub)
{
	_p_sub->attach(this);
}

concrete_observer_B::~concrete_observer_B()
{
	_p_sub->detach(this);
	if (_p_sub)
	{
		delete _p_sub;
		_p_sub = NULL;
	}
}

void concrete_observer_B::update(subject * p_sub)
{
	_st = _p_sub->get_state();
	print_info();
}

subject *concrete_observer_B::get_subject()
{
	return _p_sub;
}

void concrete_observer_B::print_info()
{
	cout<<"concrete_observer_B observer..."<<_p_sub->get_state()<<endl;
}

//main.cpp

#include "observer.h"
#include "subject.h"

int main(int argc,char **argv)
{
	//concrete_subject *p_con_sub = new concrete_subject();
	subject *p_con_sub = new concrete_subject();
	observer *p_obs_1 = new concrete_observer_A(p_con_sub);
	observer *p_obs_2 = new concrete_observer_B(p_con_sub);

	p_con_sub->set_state("old");
	p_con_sub->notify();
	p_con_sub->set_state("new");
	p_con_sub->notify();

	return 0;
}

如例所示,subject正是我们的数据,设有两个观察者,nodify函数实现数据同步,observer类的设计使用了类的组合。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值