观察者模式,又叫Observer模式或者Event模式,是用来对事件进行通知的模式,在UI框架中使用的比较多。

定义

定义对象间的一种一对多(变化)的依赖关系,以便当一个对象(Subject)的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。 — 《设计模式》 GoF

Motivation 动机

为了给某些对象建立一种通知依赖关系,即一个对象发生变化,所有的依赖对象都会得到通知。使用面向对象的技术,使得这种依赖关系弱化,具体实现方法:抽象出一个通知类,把通知的结果或者形式封装起来。

目标发送通知时,无需指定哪个观察者,通知会自动传播给所有的观察者
观察者自己觉得是否需要订阅通知,目标对象对此一无所知

代码分析

目标对象
目标对象包括一个自动生成随机数的函数,一个发送通知的函数,订阅通知的函数和取消订阅通知的函数。
这个类中添加和删除订阅都是基于抽象的观察者类而不依赖具体的实现,抽象的观察者类是稳定的。

class ValueChange
{
public:
	ValueChange();
	~ValueChange();

	/* list 支持多个观察者 */
	list<IProgress*>  progressList;

	/* 数据变化 */
	void ChangeValue();
	/* 发送通知 */
	void onProcess(int data);
	/* 添加通知 */
	void attachProcess(IProgress *progress);
	/* 删除通知 */
	void detachProdess(IProgress *progress);
};

ValueChange::ValueChange()
{
}

ValueChange::~ValueChange()
{
}

/* 数据变化 */
void ValueChange::ChangeValue()
{
	int i = rand() % 10;
	onProcess(i);
}

/* 发送通知 */
void ValueChange::onProcess(int data)
{
	list<IProgress *>::iterator itor = progressList.begin();
	while (itor != progressList.end())
	{
		(*itor)->Doprogress(data);
		itor++;
	}
}

/* 添加通知 */
void ValueChange::attachProcess(IProgress *progress)
{
	progressList.push_back(progress);
}

/* 删除通知 */
void ValueChange::detachProdess(IProgress *progress)
{
	progressList.remove(progress);
}

观察者类
观察者类是一个接口类,包括一个纯虚函数 : 显示数据

class IProgress
{
public:
	virtual ~IProgress();
	virtual void Doprogress(int data) = 0;
};

** 两个通知类 **
两个通知类继承观察者类,重写观察者类里面的纯虚函数,实现具体的通知方式,如打印数据或者打印 * 符号

class Progress1 : public IProgress
{
public:
	Progress1();
	~Progress1();

	void Doprogress(int data);
};

Progress1::~Progress1()
{
}

void Progress1::Doprogress(int data)
{
	int i = 0;
	printf("data = %d\n", data);
}

class Progress2 : public IProgress
{
public:
	Progress2();
	~Progress2();

	void Doprogress(int data);
};

Progress2::Progress2()
{
}

Progress2::~Progress2()
{
}

void Progress2::Doprogress(int data)
{
	int i = 0;
	for (i = 0; i < data; i++)
	{
		printf("*");
	}
	printf("\n");
}

主函数
主函数实现一个目标对象并且订阅了两个观察者,调用目标对象的随机数函数,查看事件的通知形式。

int main()
{
	int i = 10;
	ValueChange *val = new ValueChange;
	IProgress *pro1 = new Progress1;
	IProgress *pro2 = new Progress2;
	val->attachProcess(pro1);
	val->attachProcess(pro2);

	do {
		val->ChangeValue();
		i--;
		printf("\n");
	} while (i);
	return 0;
}

运行结果:

类图


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

装饰模式 上一篇
模板模式 下一篇