cpp: Observer Pattern II
// SupperGold.h : 此文件包含 "SupperGold" 类。Observer Pattern 观察者模式 C++ 14 // Jewelry Observer Pattern 观察者模式 // 2023年5月10日 涂聚文 Geovin Du Visual Studio 2022 edit. #pragma once #ifndef SUPPERGOLD_H #define SUPPERGOLD_H #include <iostream> #include <sstream> #include <vector> #include <list> #include "SupperNotifier.h" using namespace std; namespace GeovinDuObserverPattern { class SupperNotifier; //类前向声明 /// <summary> /// /// </summary> class SupperGold { public: //SupperNotifier* notifier; public: /// <summary> /// 构造函数 /// </summary> /// <param name="memberID"></param> /// <param name="memberName"></param> SupperGold(int memberID, string memberName) :mMemberID(memberID), mMemberName(memberName) { mFamilyID = -1; //-1表示没加入任何协会 } /// <summary> /// 析构函数 /// </summary> virtual ~SupperGold() {} public: /// <summary> /// 加入协会时设置协会ID /// </summary> /// <param name="memberID"></param> void SetFamilyID(int memberID) { mFamilyID = memberID; } /// <summary> /// 获取协会ID /// </summary> /// <returns></returns> int GetFamilyID() { return mFamilyID; } /// <summary> /// 会员说了某句话 /// </summary> /// <param name="tmpContent"></param> /// <param name="notifier"></param> void SayWords(string tmpContent, SupperNotifier* notifier); //{ // notifier->notify(this, tmpContent); // //notifier->notify(this, tmpContent); // notifier->addToList(this); //} /// <summary> /// 通知该会员接收到其他会员发送来的聊天信息,虚函数,子类可以覆盖以实现不同的动作 /// </summary> /// <param name="talker"></param> /// <param name="tmpContent"></param> virtual void NotifyWords(SupperGold* talker, string tmpContent) { //显示信息 cout << "会员:" << mMemberName << " 收到了会员:" << talker->mMemberName << " 发送的聊天信息:" << tmpContent << endl; } private: /// <summary> /// 会员ID,全局唯一 /// </summary> int mMemberID; /// <summary> /// 会员名字 /// </summary> string mMemberName; /// <summary> /// 协会ID /// </summary> int mFamilyID; }; } #endif // SupperNotifier.h : 此文件包含 "SupperNotifier" 类。Observer Pattern 观察者模式 C++ 14 // Jewelry Observer Pattern 观察者模式 // 2023年5月10日 涂聚文 Geovin Du Visual Studio 2022 edit. #pragma once #ifndef SUPERNOTIFIER_H #define SUPERNOTIFIER_H #include <iostream> #include <sstream> #include <vector> #include <list> #include "SupperGold.h" using namespace std; namespace GeovinDuObserverPattern { class SupperGold; //类前向声明 //class SupperNotifier; //类前向声明 /// <summary> /// /// </summary> class SupperNotifier { public: //SupperNotifier(string mesage):sendMessage(mesage) {} public: /// <summary> /// 把要被通知的会员加到列表中 /// </summary> /// <param name="member"></param> virtual void addToList(SupperGold* member) = 0; /// <summary> /// 把不想被通知的会员从列表中去除 /// </summary> /// <param name="member"></param> virtual void removeFromList(SupperGold* member) = 0; /// <summary> /// 通知的一些细节信息 /// </summary> /// <param name="talker"></param> /// <param name="tmpContent"></param> virtual void notify(SupperGold* talker, string tmpContent) = 0; /// <summary> /// /// </summary> virtual ~SupperNotifier() {} //void SayWords(string tmpContent, SupperNotifier* notifier); private: //string sendMessage; }; } #endif // SupperNotifier.cpp : 此文件包含 "SupperNotifier" 类。Observer Pattern 观察者模式 C++ 14 // Jewelry Observer Pattern 观察者模式 // 2023年5月10日 涂聚文 Geovin Du Visual Studio 2022 edit. #include "SupperNotifier.h" using namespace std; namespace GeovinDuObserverPattern { /// <summary> /// /// </summary> /// <param name="tmpContent"></param> /// <param name="notifier"></param> void SupperGold::SayWords(string tmpContent, SupperNotifier* notifier) { notifier->notify(this, tmpContent); //notifier->notify(this, tmpContent); notifier->addToList(this); } } // SupperShop.h : 此文件包含 "SupperShop" 类。Observer Pattern 观察者模式 C++ 14 // Jewelry Observer Pattern 观察者模式 // 2023年5月10日 涂聚文 Geovin Du Visual Studio 2022 edit. #pragma once #ifndef TALKNOTIFIER_H #define TALKNOTIFIER_H #include <iostream> #include <sstream> #include <vector> #include <list> #include <map> #include "SupperNotifier.h" #include "SupperGold.h" using namespace std; namespace GeovinDuObserverPattern { /// <summary> /// 聊天信息通知器 /// </summary> class TalkNotifier :public SupperNotifier { public: /// <summary> /// 将会员增加到协会列表中来 /// </summary> /// <param name="player"></param> virtual void addToList(SupperGold* player) { int tmpfamilyid = player->GetFamilyID(); if (tmpfamilyid != -1) //加入了某个家族 { auto iter = mFamilyList.find(tmpfamilyid); if (iter != mFamilyList.end()) { //该协会id在map中已经存在 iter->second.push_back(player); //直接把该会员加入到该协会 } else { //该协会id在map中不存在 list<SupperGold*> tmpplayerlist; mFamilyList.insert(make_pair(tmpfamilyid, tmpplayerlist));//以该协会id为key,增加条目到map中 mFamilyList[tmpfamilyid].push_back(player); //向该协会中增加第一个会员 } } } /// <summary> /// 将会员从协会列表中删除 /// </summary> /// <param name="player"></param> virtual void removeFromList(SupperGold* player) { int tmpfamilyid = player->GetFamilyID(); if (tmpfamilyid != -1) //加入了某个协会 { auto iter = mFamilyList.find(tmpfamilyid); if (iter != mFamilyList.end()) { mFamilyList[tmpfamilyid].remove(player); } } } /// <summary> /// 家族中某会员说了句话,调用该函数来通知协会中所有人 /// </summary> /// <param name="talker"></param> /// <param name="tmpContent"></param> virtual void notify(SupperGold* talker, string tmpContent) //talker是讲话的会员 { int tmpfamilyid = talker->GetFamilyID(); if (tmpfamilyid != -1) { auto itermap = mFamilyList.find(tmpfamilyid); if (itermap != mFamilyList.end()) { //遍历该会员所属协会的所有成员 for (auto iterlist = itermap->second.begin(); iterlist != itermap->second.end(); ++iterlist) { (*iterlist)->NotifyWords(talker, tmpContent); } } } } private: /// <summary> /// map中的key表示协会id,value代表该协会中所有会员列表 /// </summary> map<int, list<SupperGold*> >mFamilyList; //增加#include <map> }; } #endif // SupperCorporation.h : 此文件包含 "SupperCorporation" 类。Observer Pattern 观察者模式 C++ 14 // Jewelry Observer Pattern 观察者模式 // 2023年5月10日 涂聚文 Geovin Du Visual Studio 2022 edit. #pragma once #ifndef SUPPERCORPORATION_H #define SUPPERCORPORATION_H #include <iostream> #include <sstream> #include <vector> #include <list> #include "SupperGold.h" #include "SupperNotifier.h" using namespace std; namespace GeovinDuObserverPattern { /// <summary> /// /// </summary> class SupperCorporation :public SupperGold { public: /// <summary> /// 构造函数 /// </summary> /// <param name="memberID"></param> /// <param name="memberName"></param> SupperCorporation(int memberID, string memberName) :SupperGold(memberID, memberName) {} }; } #endif // SupperShop.h : 此文件包含 "SupperShop" 类。Observer Pattern 观察者模式 C++ 14 // Jewelry Observer Pattern 观察者模式 // 2023年5月10日 涂聚文 Geovin Du Visual Studio 2022 edit. #pragma once #ifndef SUPPERSHOP_H #define SUPPERSHOP_H #include <iostream> #include <sstream> #include <vector> #include <list> #include "SupperGold.h" #include "SupperNotifier.h" using namespace std; namespace GeovinDuObserverPattern { /// <summary> /// /// </summary> class SupperShop:public SupperGold { public: /// <summary> /// 构造函数 /// </summary> /// <param name="memberID"></param> /// <param name="memberName"></param> SupperShop(int memberID, string memberName) :SupperGold(memberID, memberName) {} }; } #endif
// GeovinDu.cpp : 此文件包含 "GeovinDu" 类。 Observer Pattern C++ 14 // Jewelry Observer Pattern 观察者模式 // 2023年5月10日 涂聚文 Geovin Du Visual Studio 2022 edit. #pragma once #ifndef GEOVINDU_H #define GEOVINDU_H #include <iostream> #include <list> #include "Gold.h" #include "GoldCommerce.h" #include "GoldCorporation.h" #include "GoldShop.h" #include "SupperCommerce.h" #include "SupperCorporation.h" #include "SupperGold.h" #include "SupperNotifier.h" #include "SupperShop.h" #include "TalkNotifier.h" using namespace std; using namespace GeovinDuObserverPattern; namespace DuJewelryObserverPattern { //extern CMyClass Myclass; class SupperGold; //类前向声明 class SupperCorporation; class SupperCommerce; /// <summary> /// /// </summary> class GeovinDu { private: public: /// <summary> /// /// </summary> void displaySimple(); /// <summary> /// /// </summary> void dipplayNotifierSimple(); }; } #endif // GeovinDu.cpp : 此文件包含 "GeovinDu" 类。 Observer Pattern C++ 14 // Jewelry Observer Pattern 观察者模式 // 2023年5月10日 涂聚文 Geovin Du Visual Studio 2022 edit. #include "GeovinDu.h" #include "SupperCommerce.h" #include "SupperCorporation.h" #include "SupperGold.h" #include "SupperNotifier.h" #include "SupperShop.h" #include "TalkNotifier.h" using namespace std; using namespace GeovinDuObserverPattern; namespace DuJewelryObserverPattern { list<Gold*> gPlayerList; //继续引用全局变量 /// <summary> /// /// </summary> void GeovinDu::displaySimple() { /**/ //创建协会会员 Gold* pplayerobj1 = new GoldCorporation(10, "张三"); //实际操作中很多数据取自数据库 pplayerobj1->SetFamilyID(100); //假设该协会会员所在的商会的商会ID是100 DuJewelryObserverPattern::gPlayerList.push_back(pplayerobj1); //加入到全局协会会员列表中 pplayerobj1->SayWords("hi,how are you."); Gold* pplayerobj2 = new GoldCorporation(20, "李四");// pplayerobj2->SetFamilyID(100); DuJewelryObserverPattern::gPlayerList.push_back(pplayerobj2); pplayerobj1->SayWords("hi,how are you."); Gold* pplayerobj3 = new GoldCommerce(30, "王五");// pplayerobj3->SetFamilyID(100); DuJewelryObserverPattern::gPlayerList.push_back(pplayerobj3); pplayerobj1->SayWords("hi,how are you."); Gold* pplayerobj4 = new GoldShop(50, "赵六");// pplayerobj4->SetFamilyID(101); //赵六和前面三人属于两个不同的商会 DuJewelryObserverPattern::gPlayerList.push_back(pplayerobj4); //for (auto it : gPlayerList) //{ // // it->SayWords("涂聚文,你好"); //} //某协会家聊天,同协会人都应该收到该信息 pplayerobj1->SayWords("全协会人立即到深圳湾公园地集合,准备散步!"); //释放资源 delete pplayerobj1; delete pplayerobj2; delete pplayerobj3; delete pplayerobj4; } /// <summary> /// /// </summary> void GeovinDu::dipplayNotifierSimple() { //创建协会会员聊天人员 GeovinDuObserverPattern::SupperGold* pMemberobj1 = new GeovinDuObserverPattern::SupperCorporation(10, "刘杰"); pMemberobj1->SetFamilyID(100); GeovinDuObserverPattern::SupperGold* pMemberobj2 = new GeovinDuObserverPattern::SupperCorporation(20, "GeovinDu"); pMemberobj2->SetFamilyID(100); GeovinDuObserverPattern::SupperGold* pMemberobj3 = new GeovinDuObserverPattern::SupperCommerce(30, "涂年生"); pMemberobj3->SetFamilyID(100); GeovinDuObserverPattern::SupperGold* pMemberobj4 = new GeovinDuObserverPattern::SupperCommerce(50, "涂聚文"); pMemberobj4->SetFamilyID(200); //创建通知器 GeovinDuObserverPattern::SupperNotifier* ptalknotify = new GeovinDuObserverPattern::TalkNotifier(); //会员增加到协会列表中来,这样才能收到协会聊天信息 ptalknotify->addToList(pMemberobj1); ptalknotify->addToList(pMemberobj2); ptalknotify->addToList(pMemberobj3); ptalknotify->addToList(pMemberobj4); //某协会会员聊天,会员都应该收到该信息 pMemberobj1->SayWords("全协会会员立即到国际宝都地集结,准备漫跑步!", ptalknotify); cout << "涂年生不想再收到协会其他成员的聊天信息了---" << endl; ptalknotify->removeFromList(pMemberobj3); //将涂年生从协会列表中删除 pMemberobj2->SayWords("请大家听从会长的调遣,结集点前往深圳湾公园!", ptalknotify); //释放资源 delete pMemberobj1; delete pMemberobj2; delete pMemberobj3; delete pMemberobj4; delete ptalknotify; } }
调用:
// ConsoleDuObserverPattern.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // Observer Pattern 观察者模式 // ConsoleDuObserverPattern.cpp : 此文件包含 "ConsoleDuObserverPattern" 类。 Observer Pattern C++ 14 // 2023年5月10日 涂聚文 Geovin Du Visual Studio 2022 edit. 文章来源《C++新经典设计模式》 王健伟编著 清华大学出版社 // #define _UNICODE #include <iostream> #include <list> #include <map> #include "GeovinDu.h" #include "Gold.h" #ifdef _DEBUG //只在Debug(调试)模式下 #ifndef DEBUG_NEW #define DEBUG_NEW new(_NORMAL_BLOCK,__FILE__,__LINE__) //重新定义new运算符 #define new DEBUG_NEW #endif #endif //#include <boost/type_index.hpp> using namespace std; //#pragma warning(disable : 4996) using namespace DuJewelryObserverPattern; int main() { _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);//程序退出时检测内存泄漏并显示到“输出”窗口 std::cout << "Hello World!!Programa Olá Mundo!涂聚文 Geovin Du\n"; GeovinDu geovin; // //geovin.displaySimple(); // geovin.dipplayNotifierSimple(); system("pause"); return 0; } // 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单 // 调试程序: F5 或调试 >“开始调试”菜单 // 入门使用技巧: // 1. 使用解决方案资源管理器窗口添加/管理文件 // 2. 使用团队资源管理器窗口连接到源代码管理 // 3. 使用输出窗口查看生成输出和其他消息 // 4. 使用错误列表窗口查看错误 // 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目 // 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件 #define UNICODE
输出:
Hello World!!Programa Olá Mundo!涂聚文 Geovin Du 会员:刘杰 收到了会员:刘杰 发送的聊天信息:全协会会员立即到国际宝都地集结,准备漫跑步! 会员:GeovinDu 收到了会员:刘杰 发送的聊天信息:全协会会员立即到国际宝都地集结,准备漫跑步! 会员:涂年生 收到了会员:刘杰 发送的聊天信息:全协会会员立即到国际宝都地集结,准备漫跑步! 涂年生不想再收到协会其他成员的聊天信息了--- 会员:刘杰 收到了会员:GeovinDu 发送的聊天信息:请大家听从会长的调遣,结集点前往深圳湾公园! 会员:GeovinDu 收到了会员:GeovinDu 发送的聊天信息:请大家听从会长的调遣,结集点前往深圳湾公园! 会员:刘杰 收到了会员:GeovinDu 发送的聊天信息:请大家听从会长的调遣,结集点前往深圳湾公园! 请按任意键继续. . .
哲学管理(学)人生, 文学艺术生活, 自动(计算机学)物理(学)工作, 生物(学)化学逆境, 历史(学)测绘(学)时间, 经济(学)数学金钱(理财), 心理(学)医学情绪, 诗词美容情感, 美学建筑(学)家园, 解构建构(分析)整合学习, 智商情商(IQ、EQ)运筹(学)生存.---Geovin Du(涂聚文)