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 发送的聊天信息:请大家听从会长的调遣,结集点前往深圳湾公园!
请按任意键继续. . .

  

 

posted @ 2023-05-12 21:45  ®Geovin Du Dream Park™  阅读(12)  评论(0编辑  收藏  举报