当前位置:网站首页>Explain observer mode
Explain observer mode
2022-06-28 08:43:00 【Jinky strange 18】
in real life , Many things do not exist independently . Let's look at a few examples
- When the double 11 is coming , Some stores do activities , Consumers will selectively consume .
- Input the wrong password many times before using the mobile phone , The phone will be displayed on N Enter the password in seconds , And return to the original state .
- When the weather forecast shows rain tomorrow , Users who go out will remember to bring umbrellas .
Exists between objects One to many Dependency of , When The state of an object changes when , All objects that depend on it are notified and automatically updated , This is it. Observer mode (Observer Pattern), The observer pattern belongs to the object behavior pattern . The observer model perfectly separates the observer from the observed object , Clear boundaries are drawn between modules , Improve the maintainability and reusability of the application .
Observer mode
The observer pattern is
1. monitor : Deal with things
2. The observer : Observe events , Notify listeners to handle events
Observer mode Of technological process : Put the events of interest to the listener ( Including the identification and type of the event ) Register with the observer , When the event comes , The observer finds the corresponding listener through the event ID and type in the registry , Notify each listener to handle the event
#include <iostream>
#include <functional>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
using namespace std;Design listeners ( abstract ) class
class Listener
{
public:
Listener(string s = " ") :str(s)
{}
// Interface for handling events ( pure depletion )
virtual void handleListenerMessage(int message)const = 0;
protected:
string str;// Listener unique id
};
class TestListener:public Listener
{
public:
TestListener(string name = " ") :Listener(name) {}
virtual void handleListenerMessage(int message)const
{
switch(message)
{
case 1:
cout << "1 recv" << endl;
break;
case 2:
cout << "2 recv" << endl;
break;
case 3:
cout << "3 recv" << endl;
break;
case 4:
cout << "4 recv" << endl;
break;
case 5:
cout << "5 recv" << endl;
break;
default:
cout << "refuse" << endl;
break;
}
}
};Design observer classes
class Oberser
{
public:
// Interface for registering events , Register events of interest to listeners to map in
void RegisterMessage(const Listener* plistener,int iMessage)//Listener* plistener: The identity of the listener itself iMessage: Events of interest
// Check whether the event has been registered , If registered , Insert value directly ; If not registered , Design a tree structure , pair Object inserted into map in
{
map<int,vector<const Listener*>>::iterator rit = mymap.find(iMessage);
if(rit == mymap.end())
{
vector<const Listener*> vec;
vec.push_back(plistener);
mymap[iMessage] = vec;
}
else
{
rit->second.push_back(plistener); //rit->first Representative Key ,second Representative value , The value is the container type ,vector The object of , You can call push Method
}
}
// Notification interface , When the event comes , Notify interested listeners to handle the event
void HandleMessage(int iMessage)
{
// The first step is to find , Why? ?
//1. The event is registered , After listening, you may cancel 2. Events from outside , No listener is interested , That is, the event is not registered , So look for
map<int,vector<const Listener*>>::iterator rit = mymap.find(iMessage);
if(rit == mymap.end())
{
cout << "no Listener instersting" << endl;
return;
}
// Find it and pass it later vector Iterator traversal vector Containers
vector<const Listener*>::iterator it = rit->second.begin();// How to return the starting position iterator ? rit Iterator pointing to the current position , its second representative vector object , You can call begin Interface returns the starting position iterator
for(it;it != rit->second.end();it++)
{
(*it)->handleListenerMessage(iMessage);//*it Represents the iterator inside the container ,const Listener* The pointer to , The pointer can call the interface handled by the listener
//it A reference becomes const Listener* The pointer to , It is equivalent to an object pointer pointing to the listener object ( Regular object ),handleListenerMessage It's a common method , Regular objects cannot call normal methods , A constant method should be given
}
}
private:
map<int,vector<const Listener*>> mymap;// Listeners register events to observers , You need a registry , use map mapping Implement a key Corresponding A collection ( There are many elements in the set ), Alternative implementation of one to many relationship
// int: Event type vector There are listeners who are interested in the event
};
int main()
{
TestListener Listener1("Listener1");
TestListener Listener2("Listener2");
TestListener Listener3("Listener3");
Oberser ob;
ob.RegisterMessage(&Listener1,1);
ob.RegisterMessage(&Listener1,3);
ob.RegisterMessage(&Listener2,2);
ob.RegisterMessage(&Listener2,3);
ob.RegisterMessage(&Listener3,1);
ob.RegisterMessage(&Listener3,2);
ob.HandleMessage(1);//1 After the incident , Which listener handles
ob.HandleMessage(4);//4 The event is not registered in the observer
return 0;
}

First, you need to know which listeners are interested in which events , How to get this information at the beginning , adopt register() Interface encapsulates events of interest to listeners in containers , An event may have multiple events of interest , So it is a one to many mapping relationship , use map Containers , One event corresponds to multiple listeners of interest , Put listeners in a collection .
Register events and interested listeners to map after , Monitoring events adopt handleMessage() The interface receives events and notifies interested listeners to handle the events . The listener only needs to implement the interface for handling events .
Suppose there is Listener registration event as follows :
listener1 1,3( monitor 1 Number Yes 1 Events and 3 event Interested in )
listener2 2,3
listener3 1,2
When 1 After the arrival of event No , To the observer handleMessage() Interface , Traverse the whole map surface , Find the right 1 No. interested listeners , Notify each listener to handle the event separately , That is to call handleListenerMessage()
Its main advantages are as follows .
- It reduces the coupling between the listener and the observer ( Abstract coupling ).
because monitor The interface depends only on the observer interface , Therefore specific The monitor of Only the instance of a class that implements the observer interface , But you don't need to know which class . Again , Because the observer depends only on monitor Interface , Therefore, the specific observer only knows that it is the realization monitor Interface , But you don't need to know which class .
2. There is a trigger mechanism between the target and the observer .
The main disadvantages are as follows .
1. If Listener and There is a circular dependency between observers , Observe person Will trigger a circular call , May cause system crash .
2. When there are many observers , Notification takes a lot of time , Program efficiency Reduce .
边栏推荐
猜你喜欢

AWS builds a virtual infrastructure including servers and networks (2)

Build an integrated kubernetes in Fedora

Kali installation configuration

AWS saves data on the cloud (3)

如何抑制SiC MOSFET Crosstalk(串擾)?

PMP从报考到拿证基本操作,了解PMP必看篇

Discussion on the improvement and application of the prepayment system in the management of electricity charge and price

What are the advantages of a differential probe over a conventional probe

电子元器件销售ERP管理系统哪个比较好?

TCP那点事
随机推荐
Kubernetes notes and the latest k3s installation introduction
为什么函数模板没有偏特化?
实现全局双指长按返回桌面
【云原生 | Kubernetes篇】深入了解Pod(六)
Large current and frequency range that can be measured by Rogowski coil
PMP从报考到拿证基本操作,了解PMP必看篇
Comment supprimer le crosstalk SiC MOSFET?
Potential safety hazards in elderly care facilities
CloudCompare&PCL 点云裁剪(基于封闭曲面或多边形)
Build an integrated kubernetes in Fedora
Power data
Avframe Memory Management API
MySQL8.0 忘记 root 密码
Protection range and optimization of motor protector for hoist equipment
[untitled]
Why are function templates not partial specialization?
[learning notes] shortest path + spanning tree
罗氏线圈可以测量的大电流和频率范围
Case tool
罗氏线圈工作原理