《Head First 设计模式》-观察者模式C++实现

       书中是让设计一个气象观测值,持续进行观测。有相应的布告板(显示器)显示不同的气象信息,并且气象站数据更新时,布告板进行相应的信息更新。所谓的观察者模式就是定义了对象之间的一对多关系,当一个对象改变时,他的所有依赖者都会受到通知并自动更新,在本文中以对应一个主题,即气象站,多个对象就作为观察者即为多个布告板。

       observer.h定义了两个基类做为主题subject和观察者observer的接口,并且将气象数据放在一个结构体里面。

#ifndef OBSERVER_H_
#define OBSERVER_H_

class observer;

struct data_weather{
	float temperature;
	float humidity;
	float pressure;
};
class subject{
public:
	subject(){
	}
	virtual ~subject(){
	}
	virtual void Notify(){
	}
	virtual void Attach(observer*){
	}
	virtual void Detach(observer*){
	}
	virtual data_weather GetState(){
		return status;
	}
	virtual void SetState(data_weather &state){
	}
private:
	data_weather status;
};

class observer{
public:
	observer(){
	}
	~observer(){
	}
	virtual void update(subject*){
	}
};

#endif
weatherdata.h这是实例化的一个气象站主题,对基类中的接口进行实现。

#ifndef WEATHERDATA_H_
#define WEATHERDATA_H_
#include<vector>
#include<iostream>
#include"observer.h"

class weatherdata :public subject{
public:
	weatherdata(){
	}
	~weatherdata(){
	}
	void Notify();
	void Attach(observer*);
	void Detach(observer*);
	data_weather GetState();
	void SetState(data_weather &state);
private:
	std::vector<observer*> all_obser;
	data_weather status;
};
#endif
weatherdata.cpp

#include"weatherdata.h"


void weatherdata::Attach(observer* pobserver)//添加一个观察者
{
	all_obser.push_back(pobserver);
	std::cout << "Add an Observer!" << std::endl;
}

void weatherdata::Detach(observer* pobserver)//删除一个观察者
{
	std::vector<observer*> ::iterator ptr;
	ptr = find(all_obser.begin(),all_obser.end(),pobserver);
	if (all_obser.end() != ptr)
	{
		all_obser.erase(ptr);
		std::cout << "Delete an Observer" << std::endl;
	}
	else
		return;
}
void weatherdata::Notify()//通知观察者状态更新
{
	std::vector<observer*>::iterator iter = this->all_obser.begin();
	for (; iter != all_obser.end(); iter++)
		{
			(*iter)->update(this);
		}
}
data_weather weatherdata::GetState()
{
	return this->status;
}
void weatherdata::SetState(data_weather &data)
{
	this->status = data;
}
allobserver.h是实例化的观察者,即多个布告板

#ifndef ALLOBSERVER_H_
#define ALLOBSERVER_H_
#include<iostream>
#include"observer.h"
#include"weatherdata.h"

class currentdisplay :public observer{
public:
	currentdisplay(){
	}
	~currentdisplay(){
	}
	
	void update(subject*psubject);
	void display();
private:

	data_weather current_data;
};

class statisticsdisplay :public observer{
public:
	statisticsdisplay(){
	}
	~statisticsdisplay(){
	}
	void update(subject*psubject){
	};
	void diplay(){
	};
};
//
//class forcastdisplay :public observer{
//	void update();
//	void diplay();
//};

#endif

allobserver.cpp

#include"allobserver.h"


void currentdisplay::update(subject*psubject)
{
	this->current_data = psubject->GetState();
	display();
}

void currentdisplay::display()
{
	std::cout << "Current condition: " << current_data.temperature << "F degrees and "
		<< current_data.humidity << "% humidity" << std::endl;
}

主函数main.cpp

#include<iostream>
#include"observer.h"
#include"allobserver.h"
#include"weatherdata.h"

int main()
{
	observer* p1 = new currentdisplay();
	subject* pSubject = new weatherdata();
	observer* p2 = new statisticsdisplay();
	pSubject->Attach(p1);
	pSubject->Attach(p2);
	data_weather old_data = { 80, 65, 30.4f };
	pSubject->SetState(old_data);
	pSubject->Notify();

	std::cout << "-------------------------------------" << std::endl;
	pSubject->Detach(p2);
	data_weather new_data = { 82, 70, 29.2f };
	pSubject->SetState(new_data);

	pSubject->Notify();

	return 0;
}

运行结果


这种模式可以使主题和观察者之间松耦合。当有新类型的观察者出现时,主题的代码不需要修改,主题只会发送通知给所有实现了观察者接口的对象。并且我们可以独立的复用主题或观察者,因为两者是松耦合,并且改变两者中的一方,并不会影响另一方。所以松耦合设计也是软件设计的一个原则,可以建立弹性的面向对象系统,灵活应对变化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值