C++ 观察者模式

什么是装饰器模观察者?

  • 它是一种行为型模式,观察者模式(Observer Pattern),也是我们熟知的发布-订阅模式(publish-subscribe)。
  • C++ 代码中观察者模式很常见, 特别是在 GUI组件编程中,不同UI在不与其他对象类耦合的前提下,针对逻辑层事件做出不同反应的方式。
  • C++ 程序员必须掌握的核心设计模式之一
如何理解观察者模式
  • 目的:
    定义对象间的一(Subject)对多( Observer)的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都获得变更通知,并被自动执行更新信息。

  • 意义:
    保证高度的协作,但低耦合,不同对象之间进行解耦并弱化关系。

代码描述
#include <iostream>
#include <list>
#include <string>
//====================================抽象接口======================================
class I_Observer {
public:
	virtual ~I_Observer(){};
	virtual void Update(const std::string& message_from_subject) = 0;
};

class I_Subject {
public:
	virtual ~I_Subject(){};
	virtual void Attach(std::shared_ptr<I_Observer> observer) = 0;
	virtual void Detach(std::shared_ptr<I_Observer> observer) = 0;
	virtual void Notify()                                     = 0;
};
//====================================被观察者======================================
class Subject : public I_Subject {
public:
	virtual ~Subject() { std::cout << "Subject delete"<<std::endl; }

	void Attach(std::shared_ptr<I_Observer> observer) override { list_observer_.emplace_back(observer); }
	void Detach(std::shared_ptr<I_Observer> observer) override { list_observer_.remove(observer); }
	void Notify() override
	{
		OutObserverCount();
		for (auto &iterator:list_observer_) {
			iterator->Update(message_);
		}
	}

	void CreateMessage(std::string message = "NULL msg")
	{
		this->message_ = message;
		Notify();
	}
	void OutObserverCount()
	{
		std::cout << "There are " << list_observer_.size() << " observers in the list." << std::endl;
	}

private:
	std::list<std::shared_ptr<I_Observer>> list_observer_;
	std::string                            message_;
};

//====================================Android系统观察者======================================
class ObserverAndroid : public I_Observer {
public:
	ObserverAndroid(std::string name) :name_(name) {}
	virtual ~ObserverAndroid(){
		std::cout << name_ <<" I was the Observer delete " << std::endl;
	}

	void Update(const std::string& message_from_subject) override
	{
		message_from_subject_ = message_from_subject;
		PrintInfo();
	}

private:
	void PrintInfo() {
		std::cout << name_ << std::endl;
	}

private:
	std::string message_from_subject_;
	std::string              name_;
};
//====================================苹果系统观察者======================================
class ObserverApple : public I_Observer {
public:
	ObserverApple( std::string name) :  name_(name) {}
	virtual ~ObserverApple() { 
		std::cout << name_ << " Apple was the Observer delete " << std::endl;
	}

	void Update(const std::string& message_from_subject) override{
		message_from_subject_ = message_from_subject;
		PrintInfo();
	}

private:
	void PrintInfo() { std::cout << name_ << " IOS NB" << std::endl; }

private:
	std::string              message_from_subject_;
	std::string              name_;
};
//====================================测试======================================
void ClientCode()
{
	//创建被观察者
	std::shared_ptr<Subject> subject   = std::make_shared<Subject>();
	//创建两个观察者并注册
	std::shared_ptr<ObserverAndroid> observer_xiaomi = std::make_shared<ObserverAndroid>("xiaomi");
	subject->Attach(observer_xiaomi);
	std::shared_ptr<ObserverAndroid> observer_vivo = std::make_shared<ObserverAndroid>("Vivo");
	subject->Attach(observer_vivo);

	//被观察者发布消息
	subject->CreateMessage("Hello World!");
	//移除一个被观察者并发布新消息
	subject->Detach(observer_vivo);
	subject->CreateMessage("Android NB");

	//创建一个新的观察者并注册
	std::shared_ptr<ObserverApple> observer_apple = std::make_shared<ObserverApple>("Apple phone");
	subject->Attach(observer_apple);
	//发布新消息
	subject->CreateMessage("Mobile NB");

	std::cout << std::endl;
}

int main()
{
	ClientCode();
	return 0;
}

运行结果
在这里插入图片描述

观察者模式的优缺点

优点:

  • 开闭原则,无需修改发布者代码就能引入新的订阅者类
  • 可以在运行时建立对象之间的联,如注册或移除等行为
  • 观察者和被观察者是松耦合

缺点:

  • 订阅者的通知顺序是随机的,很难按照指定顺序执行
  • 被观察者对象有很多的直接和间接的观察者的话,通知所有的观察者可能会花费很长的时间
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值