21 intermediary model
21.1 concept
Define a mediation role to encapsulate the interaction between a series of objects, so that the coupling between the original objects is loose, and the interaction between them can be changed independently.
Multiple classes are interrelated, showing a complex network structure and over coupling. The mediator pattern is introduced to change the relationship between classes into a star structure. Any change in a class will only affect the class itself and the mediator.
21.2 structure
Abstract intermediary role: defines the interface of the intermediary and provides abstract methods for registering and forwarding colleague object information.
Specific mediator role: implement the mediator interface, define a list to manage colleague objects, and coordinate the interaction between various colleague roles.
Abstract colleague class role: defines the interface of colleague class, saves the mediator object, provides the abstract method of colleague object interaction, and realizes the public functions of all interacting colleague classes.
Specific colleague roles: implement Abstract colleague roles. When you need to interact with other colleague objects, the mediator object is responsible for the subsequent interaction.
21.3 realization
21.3.1 UML diagram
21.3.2 code
MediatorAndPerson.h:
#ifndef _MEDIATORANDPERSON_H_ #define _MEDIATORANDPERSON_H_ #include<iostream> #include<string> #include<list> using namespace std; class Person; class Tenant; class HouseHolder; class Mediator { public: virtual void constactTenant(string message, Tenant* tenant) = 0; virtual void constactHouseHolder(string message, HouseHolder* houseHolder) = 0; }; class ConcreteMediator : public Mediator { private: list<Tenant*> tenants; list<HouseHolder*> houseHolders; public: void addHouseHolder(HouseHolder* houseHolder); void deleteHouseHolder(HouseHolder* houseHolder); void addTenant(Tenant* tenant); void deleteTenant(Tenant* tenant); void constactTenant(string message, Tenant * tenant); void constactHouseHolder(string message, HouseHolder* houseHolder); }; class Person { protected: string name; ConcreteMediator* mediator; public: Person(string name, ConcreteMediator* mediator); }; class Tenant : public Person { public: Tenant(string name, ConcreteMediator* mediator); void constact(string message); void getMessage(string message); virtual ~Tenant(); }; class HouseHolder : public Person { public: HouseHolder(string name, ConcreteMediator* mediator); void constact(string message); void getMessage(string message); virtual ~HouseHolder(); }; #endif
MediatorAndPerson.cpp:
#include"MediatorAndPsrson.h" //Intermediary class void ConcreteMediator::addHouseHolder(HouseHolder* houseHolder) { houseHolders.push_back(houseHolder); } void ConcreteMediator::deleteHouseHolder(HouseHolder* houseHolder) { houseHolders.remove(houseHolder); } void ConcreteMediator::addTenant(Tenant* tenant) { tenants.push_back(tenant); } void ConcreteMediator::deleteTenant(Tenant* tenant) { tenants.remove(tenant); } void ConcreteMediator::constactTenant(string message, Tenant* tenant) { for (auto it : this->houseHolders) { (*it).getMessage(message); } } void ConcreteMediator::constactHouseHolder(string message, HouseHolder* houseHolder) { for (auto it : this->tenants) { (*it).getMessage(message); } } //Colleague class Person::Person(string name, ConcreteMediator* mediator) { this->name = name; this->mediator = mediator; } //Tenant class Tenant::Tenant(string name, ConcreteMediator* mediator) : Person(name, mediator) { mediator->addTenant(this); } void Tenant::constact(string message) { this->mediator->constactTenant(this->name+"The requirements are:"+message, this); } void Tenant::getMessage(string message) { cout << this->name << "Message received:\n" << message << endl <<endl; } Tenant::~Tenant() { this->mediator->deleteTenant(this); } //Homeowners HouseHolder::HouseHolder(string name, ConcreteMediator* mediator) : Person(name, mediator) { mediator->addHouseHolder(this); } void HouseHolder::constact(string message) { this->mediator->constactHouseHolder(this->name + "The requirements are:" + message, this); } void HouseHolder::getMessage(string message) { cout <<this->name <<"Message received:\n" << message << endl << endl; } HouseHolder::~HouseHolder() { this->mediator->deleteHouseHolder(this); }
main.cpp:
#include"MediatorAndPsrson.h" int main() { ConcreteMediator* mediator = new ConcreteMediator(); Tenant* tenant1 = new Tenant("Renter 1", mediator); Tenant* tenant2 = new Tenant("Renter 2", mediator); HouseHolder* houseHolder1 = new HouseHolder("Homeowner 1", mediator); HouseHolder* houseHolder2 = new HouseHolder("Homeowner 2", mediator); tenant1->constact("We need a one bedroom house"); houseHolder2->constact("There is a house with three bedrooms and two living rooms"); return 0; }
21.4 advantages and disadvantages
21.4.1 advantages
Loose coupling. Encapsulate the interaction between multiple colleague objects into the mediator object, so that the coupling between colleague objects is loose, so that colleague objects can be changed and reused independently.
Centralized control interaction. The interaction of multiple colleague objects is encapsulated in the mediator object for unified management, so that when the interaction behavior changes, only the mediation object needs to be modified.
One to many association is transformed into one to one association. Make the relationship easier to understand.
21.4.2 disadvantages
When there are too many colleagues, intermediaries will become very large and difficult to maintain.
21.5 usage scenarios
There are complex reference relationships in the system, and the system structure is chaotic and difficult to understand.
When you want to create an object running between multiple classes and don't want to generate new subclasses.