当前位置:网站首页>05 observer mode
05 observer mode
2022-06-27 07:49:00 【zzyzxb】
One : An example of inefficiency caused by traversal problems
#ifdef _DEBUG // Only in Debug( debugging ) In mode
#ifndef DEBUG_NEW
#define DEBUG_NEW new(_NORMAL_BLOCK,__FILE__,__LINE__) // Redefinition new Operator
#define new DEBUG_NEW
#endif
#endif
//#include <boost/type_index.hpp>
using namespace std;
//#pragma warning(disable : 4996)
namespace nmsp1
{
class Fighter; // Class forward declaration
list<Fighter*> g_playerList;
// Player parent class ( Former combatants )
class Fighter
{
public:
Fighter(int tmpID, string tmpName) :m_iPlayerID(tmpID), m_sPlayerName(tmpName) // Constructors
{
m_iFamilyID = -1; //-1 It means that you have not joined any family
}
virtual ~Fighter() {} // Destructor
public:
void SetFamilyID(int tmpID) // When you join a family, you should set up a family ID
{
m_iFamilyID = tmpID;
}
public:
void SayWords(string tmpContent) // The player said something
{
if (m_iFamilyID != -1)
{
// The player belongs to a family , The chat content information should be transmitted to other players in the family
for (auto iter = g_playerList.begin(); iter != g_playerList.end(); ++iter)
{
if (m_iFamilyID == (*iter)->m_iFamilyID)
{
// Other players in the same family should also receive chat messages
NotifyWords((*iter), tmpContent);
}
}
}
}
private:
void NotifyWords(Fighter* otherPlayer, string tmpContent) // Other players have received chat messages from the current player
{
// display information
cout << " The player :" << otherPlayer->m_sPlayerName << " Received player :" << m_sPlayerName << " Chat messages sent :" << tmpContent << endl;
}
private:
int m_iPlayerID; // The player ID, Globally unique
string m_sPlayerName; // Player name
int m_iFamilyID; // family ID
};
//" warrior " Class player , The parent class is Fighter
class F_Warrior :public Fighter
{
public:
F_Warrior(int tmpID, string tmpName) :Fighter(tmpID, tmpName) {} // Constructors
};
//" Master " Class player , The parent class is Fighter
class F_Mage :public Fighter
{
public:
F_Mage(int tmpID, string tmpName) :Fighter(tmpID, tmpName) {} // Constructors
};
}
int main()
{
// Create gamers
nmsp1::Fighter* pplayerobj1 = new nmsp1::F_Warrior(10, " Zhang San "); // In the actual game, a lot of data is taken from the database
pplayerobj1->SetFamilyID(100); // Suppose the player's family ID yes 100
nmsp1::g_playerList.push_back(pplayerobj1); // Add to the global player list
nmsp1::Fighter* pplayerobj2 = new nmsp1::F_Warrior(20, " Li Si ");
pplayerobj2->SetFamilyID(100);
nmsp1::g_playerList.push_back(pplayerobj2);
nmsp1::Fighter* pplayerobj3 = new nmsp1::F_Mage(30, " Wang Wu ");
pplayerobj3->SetFamilyID(100);
nmsp1::g_playerList.push_back(pplayerobj3);
nmsp1::Fighter* pplayerobj4 = new nmsp1::F_Mage(50, " Zhao Liu ");
pplayerobj4->SetFamilyID(200); // Zhao Liu and the first three belong to two different families
nmsp1::g_playerList.push_back(pplayerobj4);
// When a player chats , People of the same race should receive this message
pplayerobj1->SayWords(" The whole clan immediately gathered in the swamp , Prepare to attack !");
// Release resources
delete pplayerobj1;
delete pplayerobj2;
delete pplayerobj3;
delete pplayerobj4;
std::cout << " Main thread execution completed \n";
}
Two : Bring in the observer (Observer) Pattern
The code for using the observer design pattern is as follows
#ifdef _DEBUG // Only in Debug( debugging ) In mode
#ifndef DEBUG_NEW
#define DEBUG_NEW new(_NORMAL_BLOCK,__FILE__,__LINE__) // Redefinition new Operator
#define new DEBUG_NEW
#endif
#endif
//#include <boost/type_index.hpp>
using namespace std;
//#pragma warning(disable : 4996)
namespace nmsp1
{
class Fighter; // Class forward declaration
list<Fighter*> g_playerList;
// Player parent class ( Former combatants )
class Fighter
{
public:
Fighter(int tmpID, string tmpName) :m_iPlayerID(tmpID), m_sPlayerName(tmpName) // Constructors
{
m_iFamilyID = -1; //-1 It means that you have not joined any family
}
virtual ~Fighter() {} // Destructor
public:
void SetFamilyID(int tmpID) // When you join a family, you should set up a family ID
{
m_iFamilyID = tmpID;
}
public:
void SayWords(string tmpContent) // The player said something
{
if (m_iFamilyID != -1)
{
// The player belongs to a family , The chat content information should be transmitted to other players in the family
for (auto iter = g_playerList.begin(); iter != g_playerList.end(); ++iter)
{
if (m_iFamilyID == (*iter)->m_iFamilyID)
{
// Other players in the same family should also receive chat messages
NotifyWords((*iter), tmpContent);
}
}
}
}
private:
void NotifyWords(Fighter* otherPlayer, string tmpContent) // Other players have received chat messages from the current player
{
// display information
cout << " The player :" << otherPlayer->m_sPlayerName << " Received player :" << m_sPlayerName << " Chat messages sent :" << tmpContent << endl;
}
private:
int m_iPlayerID; // The player ID, Globally unique
string m_sPlayerName; // Player name
int m_iFamilyID; // family ID
};
//" warrior " Class player , The parent class is Fighter
class F_Warrior :public Fighter
{
public:
F_Warrior(int tmpID, string tmpName) :Fighter(tmpID, tmpName) {} // Constructors
};
//" Master " Class player , The parent class is Fighter
class F_Mage :public Fighter
{
public:
F_Mage(int tmpID, string tmpName) :Fighter(tmpID, tmpName) {} // Constructors
};
}
namespace nmsp2
{
class Fighter; // Class forward declaration
class Notifier // Notifier parent class
{
public:
virtual void addToList(Fighter* player) = 0; // Add the players to be notified to the list
virtual void removeFromList(Fighter* player) = 0; // Remove players from the list who do not want to be notified
virtual void notify(Fighter* talker, string tmpContent) = 0; // Some details of the notice
virtual ~Notifier() {}
};
// Player parent class
class Fighter
{
public:
Fighter(int tmpID, string tmpName) :m_iPlayerID(tmpID), m_sPlayerName(tmpName) // Constructors
{
m_iFamilyID = -1; //-1 It means that you have not joined any family
}
virtual ~Fighter() {} // Destructor
public:
void SetFamilyID(int tmpID) // When you join a family, you should set up a family ID
{
m_iFamilyID = tmpID;
}
int GetFamilyID() // Get the family ID
{
return m_iFamilyID;
}
public:
void SayWords(string tmpContent, Notifier* notifier) // The player said something
{
notifier->notify(this, tmpContent);
}
// Notify the player to receive the chat message sent by other players , Virtual functions , Subclasses can be overridden to implement different functions
virtual void NotifyWords(Fighter* talker, string tmpContent)
{
// display information
cout << " The player :" << m_sPlayerName << " Received player :" << talker->m_sPlayerName << " Chat messages sent :" << tmpContent << endl;
}
private:
int m_iPlayerID; // The player ID, Globally unique
string m_sPlayerName; // Player name
int m_iFamilyID; // family ID
};
//" warrior " Class player , The parent class is Fighter
class F_Warrior :public Fighter
{
public:
F_Warrior(int tmpID, string tmpName) :Fighter(tmpID, tmpName) {} // Constructors
};
//" Master " Class player , The parent class is Fighter
class F_Mage :public Fighter
{
public:
F_Mage(int tmpID, string tmpName) :Fighter(tmpID, tmpName) {} // Constructors
};
// Chat message notifier
class TalkNotifier :public Notifier
{
public:
// Add players to the family list
virtual void addToList(Fighter* player)
{
int tmpfamilyid = player->GetFamilyID();
if (tmpfamilyid != -1) // Joined a family
{
auto iter = m_familyList.find(tmpfamilyid);
if (iter != m_familyList.end())
{
// The family id stay map There is already
iter->second.push_back(player); // Directly add the player to the family
}
else
{
// The family id stay map Does not exist in the
list<Fighter*> tmpplayerlist;
m_familyList.insert(make_pair(tmpfamilyid, tmpplayerlist)); // With this family id by key, Add entries to map in
m_familyList[tmpfamilyid].push_back(player); // Add the first player to the family
}
}
}
// Remove players from the family list
virtual void removeFromList(Fighter* player)
{
int tmpfamilyid = player->GetFamilyID();
if (tmpfamilyid != -1) // Joined a family
{
auto iter = m_familyList.find(tmpfamilyid);
if (iter != m_familyList.end())
{
m_familyList[tmpfamilyid].remove(player);
}
}
}
// A player in the family said something , Call this function to notify everyone in the family
virtual void notify(Fighter* talker, string tmpContent) //talker It's the talking player
{
int tmpfamilyid = talker->GetFamilyID();
if (tmpfamilyid != -1) // Joined a family
{
auto itermap = m_familyList.find(tmpfamilyid);
if (itermap != m_familyList.end())
{
// Traverse all members of the family to which the player belongs
for (auto iterlist = itermap->second.begin(); iterlist != itermap->second.end(); ++iterlist)
{
(*iterlist)->NotifyWords(talker, tmpContent);
}
}
}
}
private:
//map Medium key Means family id,value Represents the list of all players in the family
map<int, list<Fighter*>> m_familyList;
};
}
int main()
{
// Create gamers
nmsp2::Fighter* pplayerobj1 = new nmsp2::F_Warrior(10, " Zhang San "); // In the actual game, a lot of data is taken from the database .
pplayerobj1->SetFamilyID(100); // Suppose the family of the player's family ID yes 100
nmsp2::Fighter* pplayerobj2 = new nmsp2::F_Warrior(20, " Li Si ");
pplayerobj2->SetFamilyID(100);
nmsp2::Fighter* pplayerobj3 = new nmsp2::F_Mage(30, " Wang Wu ");
pplayerobj3->SetFamilyID(100);
nmsp2::Fighter* pplayerobj4 = new nmsp2::F_Mage(50, " Zhao Liu ");
pplayerobj4->SetFamilyID(200); // Zhao Liu and the first three belong to two different families
// Create notifier
nmsp2::Notifier* ptalknotify = new nmsp2::TalkNotifier();
// Players are added to the family list , Only in this way can we receive family chat messages
ptalknotify->addToList(pplayerobj1);
ptalknotify->addToList(pplayerobj2);
ptalknotify->addToList(pplayerobj3);
ptalknotify->addToList(pplayerobj4);
// A gamer chats , People of the same race should receive this message
pplayerobj1->SayWords(" The whole clan immediately gathered in the swamp , Prepare to attack !", ptalknotify);
cout << " Wang Wu doesn't want to receive any more chat messages from other members of the family ---" << endl;
ptalknotify->removeFromList(pplayerobj3); // Remove Wang Wu from the family list
pplayerobj2->SayWords(" Please follow the instructions of the patriarch , Go to the swamp !", ptalknotify);
// Release resources
delete pplayerobj1;
delete pplayerobj2;
delete pplayerobj3;
delete pplayerobj4;
delete ptalknotify;
std::cout << " Main thread execution completed \n";
}
<1>pplayerobj1->SayWords(“ The whole clan immediately gathered in the swamp , Prepare to attack !”,ptalknotify);
<2>notifier->notify(this, tmpContent);
<3>int tmpfamilyid = talker->GetFamilyID();
<4>auto itermap = m_familyList.find(tmpfamilyid);
<5>for (auto iterlist = itermap->second.begin(); iterlist != itermap->second.end(); ++iterlist) // Traverse list Containers
(*iterlist)->NotifyWords(talker,tmpContent);
<6>cout << “ The player :” << m_sPlayerName << " Received player :" << talker->m_sPlayerName << " Chat messages sent :" << tmpContent << endl;
Observer design pattern definition ( Realize the intention ): Defines a one-to-many dependency between objects , When the state of an object changes , All objects that depend on it are automatically notified .
Release - subscribe (Publish-Subscribe)
Observer mode UML chart
Observer pattern without abstracting notifier UML chart
The four roles of the observer model
a)Subject( The theme ): Observe the target , Here it means Notifier class .
b)ConcreteSubject( Specific themes ): Here it means TalkNotifier class .
c)Observer( The observer ): Here it means Fighter class .
d)ConcreteObserver( Concrete observer ): Here it means F_Warrior and F_Mage Subclass .
Observer pattern role diagram
The characteristics of the observer model
a) An abstract coupling is established between the observer and the observed object .
b) The observation target sends a notification to all observers in the observer list .
c) You can add new observers or observation targets by adding code , Comply with opening and closing principle .
3、 ... and : Apply Lenovo
a) Rescue the escort cart of family members .
b) Recommend the news to readers who like it .
c) By changing the graphics drawn by itself to truly reflect the company's sales data .
d) The turret will only be right 30 Players within meters ( Players in the list ) The attack .
边栏推荐
- ACM course term summary
- Manim math engine
- 磁选机是什么?
- 大厂工作十年,年薪40万突然被裁员,公司想抛弃你,一分情面都不会留
- ACM课程学期总结
- JS find the number of all daffodils
- Speech signal processing - concept (4): Fourier transform, short-time Fourier transform, wavelet transform
- Win10 how to manage startup items?
- (笔记)Anaconda-Navigator闪退解决方法
- 无论LCD和OLED显示技术有多好,都无法替代这个古老的显示数码管
猜你喜欢
基础知识 | js基础
(笔记)Anaconda-Navigator闪退解决方法
(resolved) NPM suddenly reports an error cannot find module 'd:\program files\nodejs\node_ modules\npm\bin\npm-cli. js‘
win10-如何管理开机启动项?
【10. 差分】
JS to determine whether the result is qualified, the range is 0-100, otherwise re-enter
2022 love analysis · panoramic report of it operation and maintenance manufacturers
Recognize the ordering of O (nlogn)
盲測調查顯示女碼農比男碼農更優秀
One person manages 1000 servers? This automatic operation and maintenance tool must be mastered
随机推荐
Win10 how to manage startup items?
L'enquête en aveugle a montré que les femmes étaient meilleures que les hommes.
JS to judge the odd and even function and find the function of circular area
JS uses the while cycle to calculate how many years it will take to grow from 1000 yuan to 5000 yuan if the interest rate for many years of investment is 5%
What is a flotation machine?
Guava scheduled task
VNC Viewer方式的远程连接树莓派
磁选机是什么?
语音信号处理-概念(二):幅度谱(短时傅里叶变换谱/STFT spectrum)、梅尔谱(Mel spectrum)【语音的深度学习主要用幅度谱、梅尔谱】【用librosa或torchaudio提取】
【批处理DOS-CMD命令-汇总和小结】-cmd的内部命令和外部命令怎么区分,CMD命令和运行(win+r)命令的区别,
Publications under nature, science and cell
Use uview to enable tabbar to display the corresponding number of tabbars according to permissions
Stream常用操作以及原理探索
游戏六边形地图的实现
2. QT components used in the project
MySQL
js输出1-100之间所有的质数并求总个数
JDBC operation MySQL example
Recognize the ordering of O (nlogn)
Speech signal processing - concept (II): amplitude spectrum (STFT spectrum), Mel spectrum [the deep learning of speech mainly uses amplitude spectrum and Mel spectrum] [extracted with librosa or torch