Poco 观察者模式(Observer Pattern) 订阅和发布某个感兴趣的通知, Observer和Notification

news2024/7/6 20:27:57

Poco 观察者模式(Observer Pattern) 订阅和发布某个感兴趣的通知, Observer和Notification

flyfish

先写一个实例代码

#include "Poco/NotificationCenter.h"
#include "Poco/Notification.h"
#include "Poco/Observer.h"
#include "Poco/NObserver.h"
#include "Poco/AutoPtr.h"
#include <iostream>
using Poco::NotificationCenter;
using Poco::Notification;
using Poco::Observer;
using Poco::NObserver;
using Poco::AutoPtr;
class BaseNotification: public Notification
{
};

class FileReadableNotification: public BaseNotification
{};
class FileWritableNotification: public BaseNotification
{};
class FileTimeoutNotification: public BaseNotification
{};


class Target
{
public:
    void handleBase(BaseNotification* pNf)
    {
        std::cout << "handleBase: " << pNf->name() << std::endl;
        pNf->release(); 
    }
    void handleRead(const AutoPtr<FileReadableNotification>& pNf)
    {
        std::cout << "handleRead: " << pNf->name() << std::endl;
    }
    void handleWrite(const AutoPtr<FileWritableNotification>& pNf)
    {
        std::cout << "handleWrite: " << pNf->name() << std::endl;
    }
};


int main(int argc, char** argv)
{
    NotificationCenter nc;
    Target target;
    nc.addObserver(Observer<Target, BaseNotification>(target, &Target::handleBase));
    nc.addObserver(NObserver<Target, FileReadableNotification>(target, &Target::handleRead));
    nc.addObserver(NObserver<Target, FileWritableNotification>(target, &Target::handleWrite));

    nc.postNotification(new BaseNotification);
    nc.postNotification(new FileReadableNotification);
    nc.postNotification(new FileWritableNotification);


    nc.removeObserver(Observer<Target, BaseNotification>(target, &Target::handleBase));
    nc.removeObserver(NObserver<Target, FileReadableNotification>(target, &Target::handleRead));
    nc.removeObserver(NObserver<Target, FileWritableNotification>(target, &Target::handleWrite));
    return 0;
}

Observer是plain pointer
NObserver是 smart pointer

普通指针

typedef void (C::*Callback)(N*);

智能指针

typedef AutoPtr<N> NotificationPtr;
typedef void (C::*Callback)(const NotificationPtr&);

普通指针和智能指针按照各自的使用方式使用

Target通过NotificationCenteraddObserver()方法订阅感兴趣的notification
Target通过NotificationCenterremoveObserver()方法取消订阅感兴趣的notification

例如本实例对FileReadableNotificationFileWritableNotification感兴趣,
FileTimeoutNotification这个notification不感兴趣,那就不订阅也不用取消订阅。
派送notification是由NotificationCenterpostNotification()方法进行派送
target只要订阅该notification,target就会收到notification

通知某个target发生了什么事。
在这里插入图片描述

依据Poco源码
C对应Target Class
N对应​Notification Class

NObserver

template <class C, class N>
class NObserver: public AbstractObserver
{
public:
	typedef AutoPtr<N> NotificationPtr;
	typedef void (C::*Callback)(const NotificationPtr&);

	NObserver(C& object, Callback method):
		_pObject(&object),
		_method(method)
	{
	}

	NObserver(const NObserver& observer):
		AbstractObserver(observer),
		_pObject(observer._pObject),
		_method(observer._method)
	{
	}

	~NObserver()
	{
	}

	......
private:
	NObserver();

	C*       _pObject;
	Callback _method;
	mutable Poco::Mutex _mutex;
};

Observer

template <class C, class N>
class Observer: public AbstractObserver
{
public:
	typedef void (C::*Callback)(N*);

	Observer(C& object, Callback method):
		_pObject(&object),
		_method(method)
	{
	}

	Observer(const Observer& observer):
		AbstractObserver(observer),
		_pObject(observer._pObject),
		_method(observer._method)
	{
	}

	~Observer()
	{
	}
......
private:
	Observer();

	C*       _pObject;
	Callback _method;
	mutable Poco::Mutex _mutex;
};

NotificationCenter

class Foundation_API NotificationCenter
	/// A NotificationCenter is essentially a notification dispatcher.
	/// It notifies all observers of notifications meeting specific criteria.
	/// This information is encapsulated in Notification objects.
	/// Client objects register themselves with the notification center as observers of
	/// specific notifications posted by other objects. When an event occurs, an object
	/// posts an appropriate notification to the notification center. The notification
	/// center invokes the registered method on each matching observer, passing the notification
	/// as argument.
	///
	/// The order in which observers receive notifications is undefined.
	/// It is possible for the posting object and the observing object to be the same.
	/// The NotificationCenter delivers notifications to observers synchronously.
	/// In other words the postNotification() method does not return until all observers have
	/// received and processed the notification.
	/// If an observer throws an exception while handling a notification, the NotificationCenter
	/// stops dispatching the notification and postNotification() rethrows the exception.
	///
	/// In a multithreaded scenario, notifications are always delivered in the thread in which the
	/// notification was posted, which may not be the same thread in which an observer registered itself.
	///
	/// The NotificationCenter class is basically a C++ implementation of the NSNotificationCenter class
	/// found in Apple's Cocoa (or OpenStep).
	///
	/// While handling a notification, an observer can unregister itself from the notification center,
	/// or it can register or unregister other observers. Observers added during a dispatch cycle
	/// will not receive the current notification.
	///
	/// The method receiving the notification must be implemented as
	///     void handleNotification(MyNotification* pNf);
	/// The handler method gets co-ownership of the Notification object
	/// and must release it when done. This is best done with an AutoPtr:
	///     void MyClass::handleNotification(MyNotification* pNf)
	///     {
	///         AutoPtr<MyNotification> nf(pNf);
	///         ...
	///     }
	///
	/// Alternatively, the NObserver class template can be used to register a callback
	/// method. In this case, the callback method receives the Notification in an
	/// AutoPtr and thus does not have to deal with object ownership issues:
	///     void MyClass::handleNotification(const AutoPtr<MyNotification>& pNf)
	///     {
	///         ...
	///     }
{
public:
	NotificationCenter();
		/// Creates the NotificationCenter.

	~NotificationCenter();
		/// Destroys the NotificationCenter.

	void addObserver(const AbstractObserver& observer);
		/// Registers an observer with the NotificationCenter.
		/// Usage:
		///     Observer<MyClass, MyNotification> obs(*this, &MyClass::handleNotification);
		///     notificationCenter.addObserver(obs);
		///
		/// Alternatively, the NObserver template class can be used instead of Observer.

	void removeObserver(const AbstractObserver& observer);
		/// Unregisters an observer with the NotificationCenter.

	bool hasObserver(const AbstractObserver& observer) const;
		/// Returns true if the observer is registered with this NotificationCenter.

	void postNotification(Notification::Ptr pNotification);
		/// Posts a notification to the NotificationCenter.
		/// The NotificationCenter then delivers the notification
		/// to all interested observers.
		/// If an observer throws an exception, dispatching terminates
		/// and the exception is rethrown to the caller.
		/// Ownership of the notification object is claimed and the
		/// notification is released before returning. Therefore,
		/// a call like
		///    notificationCenter.postNotification(new MyNotification);
		/// does not result in a memory leak.

	bool hasObservers() const;
		/// Returns true iff there is at least one registered observer.
		///
		/// Can be used to improve performance if an expensive notification
		/// shall only be created and posted if there are any observers.

	std::size_t countObservers() const;
		/// Returns the number of registered observers.

	static NotificationCenter& defaultCenter();
		/// Returns a reference to the default
		/// NotificationCenter.

private:
	typedef SharedPtr<AbstractObserver> AbstractObserverPtr;
	typedef std::vector<AbstractObserverPtr> ObserverList;

	ObserverList  _observers;
	mutable Mutex _mutex;
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/592202.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Jetpack Hilt 框架的基本使用

什么是 Hilt&#xff1f; Hilt 是一个功能强大、用法简单的依赖注入框架&#xff0c;于 2020 年加入到 Jetpack 家族中。它是 Android 团队联系了 Dagger2 团队&#xff0c;一起开发出来的一个专门面向 Android 的依赖注入框架。相比于 Dagger2&#xff0c;Hilt 最明显的特征就…

Flutter 笔记 | Flutter 核心原理(四)绘制流程

Vsync 机制 在分析首帧渲染的过程中&#xff0c;可以发现Render Tree的渲染逻辑&#xff08;handleDrawFrame方法&#xff09;是直接执行的&#xff0c;但是后续每一帧的渲染都是Framework的主动调用导致的吗&#xff1f;实际上并非如此&#xff0c;也不能如此。试想一下&…

【017】C++ 指针变量详解,理解指针变量

C 指针变量详解 引言一、内存概述二、指针变量2.1、地址和指针变量的关系2.2、定义指针变量2.3、指针变量的初始化2.4、指针类型2.5、案例2.6、注意事项 三、数组元素的指针3.1、概述3.2、在使用中 [ ] 就是 *()的缩写3.3、指向同一数组的元素的两个指针变量间的关系 四、字符串…

6月销量狂欢季:测评自养号助力,引爆跨境电商销量!

随着夏季的到来&#xff0c;跨境电商卖家们迎来了一个极佳的销售机会。6月作为夏季的重要节点&#xff0c;各种活动和节日都为卖家们提供了引流和销售的良机。然而&#xff0c;要真正实现销量的爆发&#xff0c;单纯依靠传统的营销手段可能难以达到预期的效果。在这篇文章中&am…

AI+边缘,是如何加速制造转型的?

在现代工业中&#xff0c;提起智慧工厂、智能制造有一个经久不衰的话题&#xff0c;那便是IT和OT的融合。 IT&#xff08;Information Technology&#xff09;部门专注于处理数据&#xff0c;整个业务系统需要它来维持运营。而OT&#xff08;Operation Technology&#xff09;…

2023智源大会议程公开 |智能的物质基础专题论坛

6月9日&#xff0c;2023北京智源大会&#xff0c;将邀请这一领域的探索者、实践者、以及关心智能科学的每个人&#xff0c;共同拉开未来舞台的帷幕&#xff0c;你准备好了吗&#xff1f;与会知名嘉宾包括&#xff0c;图灵奖得主Yann LeCun、图灵奖得主Geoffrey Hinton、OpenAI创…

基于OA的采购系统和专业的招标采购管理系统区别

当前采购信息化百家争鸣&#xff0c;既有初级版的审批和记录电子化&#xff0c;也有中级版的业务全流程电子化&#xff0c;还有升级版的数智化创新形式&#xff08;如电商平台、智能评标、供应商风险评估、专家行为画像、大数据统计分析等&#xff09;。 近年来&#xff0c;招标…

Zotero文献在word中的引用

前提 确保你的word中有Zotero插件。如下图示&#xff1a; 具体操作 Step01 Zeroto中下载样式 在Zotero中添加相应的文献样式&#xff0c;具体如下&#xff1a; 打开Zotero“编辑”中的首选项&#xff0c;打开“引用”&#xff0c;从“获取更多样式”中搜寻你想要的文献样…

JAVA开发(手工处理数据库表数据的一些示例算法)

背景&#xff1a; 在项目开发中&#xff0c;有时候需要手动处理一下数据库表的数据。涉及到数据得到备份、恢复&#xff0c;清洗&#xff0c;计算&#xff0c;合并等操作。 举例记录一下最近对数据的一些处理过程。 1、对数据表进行数据量统计 select count(*) from table…

API接口的重要性和好处|附加淘宝api接口展示案例|商品数据采集演示

随着互联网的发展&#xff0c;API接口已经成为许多企业进行信息交流和数据管理的重要工具。通过API接口&#xff0c;企业之间能够快速、可靠地进行数据传输和信息共享&#xff0c;从而提高了企业的生产效率和服务质量。以下是API接口的重要性和好处的文章&#xff1a; 1.提高生…

Zabbix从入门到精通以及案例实操系列

1、Zabbix入门 1.1、Zabbix概述 Zabbix是一款能够监控各种网络参数以及服务器健康性和完整性的软件。Zabbix使用灵活的通知机制&#xff0c;允许用户为几乎任何事件配置基于邮件的告警。这样可以快速反馈服务器的问题。基于已存储的数据&#xff0c;Zabbix提供了出色的报告和…

5.2.2 IP地址的分配和使用

5.2.2 IP地址的分配和使用 我们已经学习了分类的IP地址&#xff0c;我们就来一起学习一下在实际的应用中IP地址是如何分配和使用的。在最初的IP地址编址方案中&#xff0c;因特网的每个物理网络都必须被分配一个唯一的网络地址&#xff0c;该网络上的主机每个主机都使用该网络…

Jenkins——maven 插件配置

文章目录 一、Maven 的集成二、在执行job的机器上安装好maven三、下载 maven 插件四、配置全局工具五、Maven 相关使用1、新建 job2、自由风格 job 中命令行使用 mvn 命令3、构建操作 一、Maven 的集成 在 Jenkins 上构建 Java 项目时需要使用 Maven 来进行构建打包 二、在执…

【笔记】微机原理及接口技术2 -- 存储器与IO接口技术

目录 存储器存储器分类存储器常用性能指标半导体存储器随机存取存储器 RAM动态随机存储器 DRAM三态缓冲器只读存储器 ROM存储器与 CPU 链接存储空间扩展方式内存寻址方法&#xff08;片选方式&#xff09;存储器小节思考题 I/O 接口技术IO 接口概述IO 端口编址寻址输入输出控制…

让仓库“零误差”,WMS仓库管理系统助力供应链升级

现代供应链的核心是以消费者和库存管理为中心&#xff0c;通过降低库存来提高产品的流通速度和供应链效率。而在信息技术快速发展的今天&#xff0c;企业的库存管理也面临着新的挑战&#xff1a; 1.仓库货品种类多&#xff0c;数量多&#xff0c;且摆放混乱&#xff0c;加大了查…

RWKV – transformer 与 RNN 的强强联合

在 NLP (Natural Language Processing, 自然语言处理) 领域&#xff0c;ChatGPT 和其他的聊天机器人应用引起了极大的关注。每个社区为构建自己的应用&#xff0c;也都在持续地寻求强大、可靠的开源模型。自 Vaswani 等人于 2017 年首次提出 Attention Is All You Need 之后&am…

SAP-MM-发票行项目格式

目的&#xff1a;SAP提供标准事物代码屏幕变式&#xff0c;但因各个公司运用的方式不同&#xff0c;可采用屏幕变式进行自定义&#xff0c;方便最终用户使用&#xff1b; 方案&#xff1a;采用屏幕变式T-CODE&#xff1a;OLMRLIST对相应事物代码进行调整&#xff1a; 案例&am…

ASCII Unicode UTF-8等等编码介绍

目录 背景 Unicode UTF-8 ISO-8859-1 GB2312和GBK ANSI UTF-16LE 和UTF-16BE UTF-16 LE 和BE是什么 如何处理字节序问题 "带有BOM的UTF-8"又是什么&#xff1f; 背景 由于计算机是美国人发明的&#xff0c;因此最早只有127个字母被编码到计算机中&#x…

1.5k star,搭建一个属于自己或团队的WIKI知识管理系统

项目简介 zyplayer-doc是一款适合团队和个人使用的WIKI文档管理工具&#xff0c;同时还包含数据库文档、Api接口文档。 体验地址&#xff1a;http://zyplayer.com 在线文档&#xff1a;http://doc.zyplayer.com 各模块介绍 zyplayer-doc-manage 文档管理后台 具有项目模块…

ue4技术方向学习路线如何安排?

作为初学者&#xff0c;您可能会感到UE4&#xff08;Unreal Engine 4&#xff09;的学习曲线很陡峭。但是&#xff0c;只要您有一个良好的学习路线和资源&#xff0c;就可以轻松地掌握UE4技术方向。下面是一个可以帮助您快速入门UE4技术方向的学习路线安排。 第一阶段&#xff…