Observer model suggestions collection of design patterns

Posted by marlonbtx on Mon, 20 Dec 2021 11:06:09 +0100

In daily life, traffic lights direct the increasingly crowded urban traffic. When the red light is on, the car stops; When the green light is on, the car continues to move forward; In this process, the traffic light is the observation target of the car, and the car is the observer. With the change of traffic lights, the behavior of cars will also change. A traffic light can command multiple cars. In the software system, there is a similar relationship between some objects, such as traffic lights and cars. The change of the state or behavior of one object will lead to the change of the state or behavior of other objects, and there will be linkage between them. It is the so-called "pull one and move the whole body". In order to better describe the one to many interaction between objects, the observer model came into being.

1, Design of multiplayer online game Design

Demand background: Company M wants to develop a multiplayer online game. In the game, multiple game players can join the same team to form an alliance. When a member of the team receives an enemy attack, it will send a notice to all other allies, and the allies will respond after receiving the notice. The developers of M company need to provide a design scheme to realize the linkage between team members.

Through analysis, the developers of M company found that the linkage process between team members in the system can be briefly described as follows:

Alliance members receive attack = > send notification to allies = > allies respond

If each alliance member needs to hold the information of allies in order to inform each ally in time, it will cost a lot of system overhead. Therefore, the developers of M company decided to introduce a new role "team control center" to maintain and manage the information of all members of each team, as shown in the following figure:

Two observer model

Observer pattern is one of the most frequently used design patterns. It is used to establish a dependency relationship between objects. When an object changes, it will automatically notify other objects, and other objects will respond accordingly.

2.1 observer mode class diagram

Note: because the Player needs to send messages to the control center, and the control center needs to send messages to all players, there is a problem that header files refer to each other in the implementation process. IControlCenter class is introduced.

2.2 code implementation

(1) Abstract Observer class

class IObserver
{
public:
    IObserver(char *pName = NULL){}
    ~IObserver(){}

    virtual void Help() = 0;
    virtual void BeAttacked(IControlCenter *pControlCenter) = 0;
};

(2) Entity CPlayer class

class Player : public IObserver
{
public:
    Player(char *pName = NULL)
    {
        size_t nLen = strlen(pName);
        memcpy(m_pName, pName, nLen + 1);
    }
    ~Player(){}

    void Help()
    {
        cout << m_pName << ":" << "Hold on, support now!" << endl;
    }

    void BeAttacked(IControlCenter *pControlCenter)
    {
        cout << m_pName << ":" << "I'm under attack, request support!" << endl;
        pControlCenter->NotifyObserver(m_pName);
    }

private:
    char m_pName[NAME_LENGTH];
};

(3) Abstract control center

#pragma once

class IControlCenter
{
public:
    IControlCenter(){}
    ~IControlCenter(){}

    virtual void NotifyObserver(char* pName) = 0;
};

(4) Entity control center

#pragma once
#include <map>
using namespace std;

#include "IControlCenter.h"
#include "IObserver.h"
class CControlCenter:public IControlCenter
{
public:
    CControlCenter(){}
    ~CControlCenter(){}

    void Regesiter(char* pName, IObserver* pObserver)
    {
        m_ObserverMap[pName] = pObserver;
        cout << "Notice:" << pName <<" " << "Join the team!" << endl;
    }

    void UnRegister(char *pName)
    {
        map<char*, IObserver*>::iterator iter;
        for (iter = m_ObserverMap.begin(); iter != m_ObserverMap.end(); iter ++)
        {
            if (0 == strcmp(pName, iter->first))
            {
                m_ObserverMap.erase(iter);
                cout << pName <<" " << "Leave the team!" << endl;
                break;
            }
        }
    }

    void NotifyObserver(char* pName)
    {
        cout << "Notice:" << "Allies,"<< pName <<"Being attacked" << endl;
        map<char*, IObserver*>::iterator iter;
        for (iter = m_ObserverMap.begin(); iter != m_ObserverMap.end(); iter ++)
        {
            if (0 != strcmp(pName, iter->first))
            {
                IObserver *pPlayer = iter->second;
                pPlayer->Help();
            }
        }
    }

private:
    map<char*, IObserver*> m_ObserverMap;
};

2.3 testing

(1) Test code

#include "stdio.h"
#include "ControlCenter.h"
#include "IObserver.h"
void main()
{
    CControlCenter *pControlCenter = new CControlCenter();
    IObserver *pPlayer1 = new Player("Zhang San");
    IObserver *pPlayer2 = new Player("Li Si");
    IObserver *pPlayer3 = new Player("Wang Mazi");
    pControlCenter->Regesiter("Zhang San", pPlayer1);
    pControlCenter->Regesiter("Li Si", pPlayer2);
    pControlCenter->Regesiter("Wang Mazi",pPlayer3);
    pPlayer1->BeAttacked(pControlCenter);
}

(2) Results

3, Observer mode and MVC

In the current popular MVC The observer mode is also applied in the (model view controller) structure, which includes three roles: model, view and controller. The model can correspond to the observation target in the observer mode, while the view corresponds to the observer, and the controller acts as an intermediary between the two. When the data of the model layer changes, the view will automatically change its display content, as shown in the following figure Show:

4, Observer mode summary

4.1 main advantages

(1) separation of presentation layer and data logic layer can be realized = > various presentation layers can act as specific observers

(2) support broadcast communication. The observation target will send a notification to the registered observer object = > simplify the difficulty of one to many system design

(3) Add a new observer without modifying the original system code = > meet the opening and closing principle

4.2 main disadvantages

(1) if an observation target has many direct and indirect observers = > it will take a lot of time for all observers to receive the notification

(2) if there is a cyclic dependency between the observer and the observation target = > it may lead to system crash

4.3 application scenarios

(1) an abstract model has two aspects, one of which depends on the other = > encapsulated to make it change and reuse independently

(2) the change of one object will lead to the change of one or more other objects, but I don't know how many objects will change = > the most familiar stranger

Publisher: full stack programmer, stack length, please indicate the source for Reprint: https://javaforall.cn/120141.html Original link: https://javaforall.cn