设计模式之观察者模式

设计模式的观察的模式究竟是怎么样的呢?它的叫法有多种,不过我们需要知道的是它的原理而非它的名字是怎么样称呼的。

这里,我们把它们看成是:订阅者--发布者的关系。

在说这个模式之前,我们或许更应该知道这个模式可以怎么来用?作用是什么?

其实,它的原理并不难,我们举的例子是报社与订报人的关系。我们想想,如果报社有最新的报纸出了,报社就会给每个订报人发布一条有报纸出了的消息,让每个订报人都能够看到。

这么看来,我们就看可以知道,报社其实充当的就是一个管理订报人的角色。然后有情况的时候,统一发布一条消息让订阅者知道。这样就起到了类似一键更新的功能。

好,说了这么多,我们看看具体的实现的步骤吧。

首先,你需要给你的发布者和订阅者抽象出一系列方法,然后再通过继承来实现这些方法。最后,就可以实例化出来进行一一匹配了。

或许你会想到,为什么不直接实现出方法呢?其实,我也不是很清楚,不过,我可以肯定的是,因为抽象的方法,可以让你的思路更加清晰。

好了,下面就直接来看看我用C++实现的观察者模式的代码吧:

#include<iostream>
#include<string>
#include<vector>

using namespace std;

//订阅者抽象方法
class PeopleInterface {
public:
	//实现自我更新
	virtual void update(string msg) = 0;
};
//订阅者抽象方法的具体实现
class People
	:public PeopleInterface
{
public:
	//实例化时给订阅者定义一个名字
	People(string name)
	{
		m_name = name;
	}
	//实现自我更新:通过收到发布者的消息来实现自我的更新
	virtual void update(string msg)
	{
		cout <<m_name<< "收到了消息:" << msg<<endl;
	}
private:
	string m_name;
};
//发布者抽象方法
class OfficeInterface
{
public:
	virtual void addObserver(People *p) = 0;
	virtual void deleteObserver(People *p) = 0;
	virtual void sendMsg(string s) = 0;
};
//发布者抽象方法的具体实现
class Brightoffice
	:public OfficeInterface
{
public:
	//添加订阅者
	virtual void addObserver(People *p)
	{
		this->oldPeople_vec.push_back(p);
	}
	//删除订阅者
	virtual void deleteObserver(People *p)
	{
		vector<People*>::iterator iter = oldPeople_vec.begin();
		for (iter; iter != oldPeople_vec.end(); iter++)
		{
			if (*iter == p){
				oldPeople_vec.erase(iter);
				return;
			}
		}

	}
	//给订阅者发布更新消息
	virtual void sendMsg(string msg)
	{
		People *temp;
		for (int i = 0; i < oldPeople_vec.size(); i++)
		{
			temp = oldPeople_vec.at(i);
			temp->update(msg);
		}
	}
private:
	vector<People*>oldPeople_vec;
};

int main()
{
	//实例出一个发布者
	auto office = new Brightoffice();
	//实例出多个订阅者
	auto p1 = new People("张三");
	auto p2 = new People("李四");
	auto p3 = new People("王五");
	//将订阅者添加到已经实例化出来的发布者中
	office->addObserver(p1);
	office->addObserver(p2);
	office->addObserver(p3);
	//发布者消息更新,这时每个订阅者都会收到来自发布者的更新消息
	office->sendMsg("新的报纸出了!");
	//突然李四不想再定这家报社的报纸了,退出报社。此时将不再接收到这家报社的更新消息
	cout << "李四退出了报社!" << endl;
	office->deleteObserver(p2);
	office->sendMsg("新的报纸又出了");
	getchar();
	return 0;
}
这里我用了STL库中的vector来进行订阅者的存储,其实可以使用其他的容器。

其实作为一个发布者,这里我仅仅实现了简单的添加与删除,其实还可以更完整一点,就是可以添加查找某个订阅者等等。

结果如下:


观察者模式其实也是挺有用的,比如在游戏中,服务器要给客户端的玩家发送系统公告等消息。好了,希望这篇文章对读者有帮助~大笑

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值