C++设计模式 | Observer 观察者模式详解

10 篇文章 0 订阅
6 篇文章 0 订阅

观察者模式介绍

观察者模式的动机

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

观察者模式解决什么问题

一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。

观察者模式的使用场合

在以下任一情况下都可以使用观察者模式:

  • 当一个抽象模型有两个方面,其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立的改变和复用;
  • 一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
  • 当一个对象必须通知其它对象,而它又不能假定其它对象是谁;也就是说,你不希望这些对象是紧密耦合的。

观察者模式的结构和实现

结构

观察者模式中包含以下角色

【1】Subject(目标)

  • 目标知道它的观察者。可以有任意多个观察者观察同一个目标;
  • 提供注册和删除观察者对象的接口。

【2】Observer(观察者)

  • 为那些在目标发生改变时需获得通知的对象定义一个更新接口。

【3】ConcreteSubject(具体目标)

  • 将有关状态存入各ConcreteObserver对象;
  • 当它的状态发生改变时,向它的各个观察者发出通知。

【4】ConcreteObserver(具体观察者)

  • 维护一个指向ConcreteSubject对象的引用;
  • 存储有关状态,这些状态应与目标的状态保持一致;
  • 实现Observer的更新接口以使自身状态与目标的状态保持一致。
实现
  • 当具体目标ConcreteSubject 发生任何可能导致其观察者与其本身状态不一致的改变时,它将通知它的各个观察者
  • 在得到一个具体目标的改变通知后,具体观察者对象ConcreteObserver可向目标对象查询信息。ConcreteObserver使用这些信息以使它的状态与目标对象的状态一致。

应用实例代码示例

示例:拍卖的时候,拍卖师观察最高标价,然后通知给其他竞价者竞价。

// 观察者模式.cpp : 定义控制台应用程序的入口点。
//

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

class Abstract_Buyer	//抽象竞价的人(观察者)
{
public:
	virtual void updata(int val) = 0;
};

class Buyer1 :public Abstract_Buyer	//具体竞价的人(观察者)
{
public:
	Buyer1()
	{
		cout << "Buyer1 adding!" << endl;
	}
	void updata(int val);
};

class Buyer2 :public Abstract_Buyer	//具体竞价的人(观察者)
{
public:
	Buyer2()
	{
		cout << "Buyer2 adding!" << endl;
	}
	void updata(int val);
};

class Buyer3 :public Abstract_Buyer	//具体竞价的人(观察者)
{
public:
	Buyer3()
	{
		cout << "Buyer3 adding!" << endl;
	}
	void updata(int val);
};

class Abstract_Seller	//抽象拍卖者(目标)
{
public:
	//添加竞价的人
	virtual void AddBuyer(Abstract_Buyer* buyer) = 0;
	//删除竞价的人
	virtual void DelBuyer(Abstract_Buyer* buyer,int index) = 0;
	//通知所有竞价的人
	virtual void Notify() = 0;
	//买家叫价
	virtual void SetBuyerPrice(int tmpprice,int i) = 0;
	//卖家设置初始价格
	virtual void SetSallerPrice(int tmpprice) = 0;
};

class Seller :public Abstract_Seller	//具体化拍卖者(目标)
{
public:
	//添加竞价的人
	void AddBuyer(Abstract_Buyer* buyer)
	{
		buyerlist.push_back(buyer);
	}
	//删除竞价的人
	void DelBuyer(Abstract_Buyer* buyer,int index)
	{
		buyerlist.remove(buyer);
		for (int i = index; i < 3; ++i)
		{
			if (i != 2)
			{
				price[i] = price[i + 1];
			}
		}
	}
	//通知所有竞价的人
	void Notify()
	{
		auto it = buyerlist.begin();
		int personindex = 0;
		while (it != buyerlist.end())
		{
			(*it)->updata(price[personindex++]);
			++it;
		}
	}
	//买家叫价
	void SetBuyerPrice(int tmpprice, int i)
	{
		price[i] = tmpprice;
	}
	//卖家设置初始价格
	void SetSallerPrice(int tmpprice)
	{
		for (int i = 0; i < 3; ++i)
		{
			price[i] = tmpprice;
		}
	}
private:
	list<Abstract_Buyer*>buyerlist;
	int price[3];
};

void Buyer1::updata(int val)
{
	cout << "Buyer1 add price " << val << endl;
}
void Buyer2::updata(int val)
{
	cout << "Buyer2 add price " << val << endl;
}
void Buyer3::updata(int val)
{
	cout << "Buyer3 add price " << val << endl;
}


int main()
{
	//创建三位竞价者(观察者)
	Abstract_Buyer *buyer1 = new Buyer1;
	Abstract_Buyer *buyer2 = new Buyer2;
	Abstract_Buyer *buyer3 = new Buyer3;

	//创建一位拍卖者(目标)
	Abstract_Seller *seller = new Seller;
	
	//将三位竞价者添加到拍卖者
	seller->AddBuyer(buyer1);
	seller->AddBuyer(buyer2);
	seller->AddBuyer(buyer3);
	cout << endl;

	//卖家定初始价
	seller->SetSallerPrice(100);
	seller->Notify();
	cout << endl;

	//买家出价
	buyer1->updata(200);
	seller->SetBuyerPrice(200, 0);
	seller->Notify();
	cout << endl;
	
	//买家退出竞价
	seller->DelBuyer(buyer1, 0);
	seller->Notify();

	delete seller;
	delete buyer1;
	delete buyer2;
	delete buyer3; 

	return 0;
}

#endif

在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值