Intermediary model (behavior type)

The mediator pattern is used to reduce the communication complexity between multiple objects and classes. This pattern provides an intermediary class, which usually handles communication between different classes and supports loose coupling, making the code easy to maintain. The intermediary model is a behavioral model.

In real life, there are many intermediary models, such as QQ game platform, chat room, QQ group, SMS platform and real estate agency. Whether it is a QQ game or a QQ group, they all act as an intermediate platform. QQ users can log in to this intermediate platform to communicate with other QQ users. Without these intermediate platforms, if we want to chat with friends, we may need to face to face Okay. Telephone and SMS are also an intermediate platform. With this intermediate platform, each user should not directly depend on other users, but only on this intermediate platform. All operations are distributed by the intermediate platform.

The mediator pattern defines an intermediary object to encapsulate the interaction between a series of objects. The intermediary eliminates the need to explicitly reference each other between objects, which reduces the coupling and can independently change the interaction between them.

Introduction

Intent: Use an intermediary object to encapsulate a series of object interactions. The intermediary eliminates the need for objects to explicitly reference each other, thereby loosening their coupling and independently changing the interaction between them.

Main solution: There are a lot of associations between objects and objects, which will inevitably lead to a complicated structure of the system. At the same time, if an object changes, we also need to track the objects associated with it and make corresponding processing .

When to use: Multiple classes are coupled to each other to form a network structure.

How to solve: Separate the above network structure into a star structure.

Key code: Communication between objects Colleague is encapsulated into a class and handled separately.

Application examples:  1. Before China joined the WTO, various countries traded with each other, and the structure was complicated. Now, each country trades with each other through the WTO. 2. Airport dispatching system. 3. MVC framework, where C (controller) is the intermediary between M (model) and V (view).

Advantages:  1. Reduce the complexity of the class and convert one-to-many to one-to-one. 2. Decoupling between classes. 3. In line with Dimit's principle.

Disadvantages: The intermediary will be huge and complicated to maintain.

Usage scenarios:  1. There are more complicated reference relationships between objects in the system, which leads to chaotic dependency structure and it is difficult to reuse the object. 2. I want to encapsulate the behavior in multiple classes through an intermediate class, but do not want to generate too many subclasses.

Note: It should not be used when the duties are confusing.


Implementation 1

We demonstrate the intermediary model through a chat room example. In an example, multiple users can send messages to a chat room, and the chat room displays messages to all users. We will create two classes  ChatRoom  and  User . User  objects use the  ChatRoom  method to share their messages.

MediatorPatternDemo , our demo class uses the  User  object to display the communication between them.

UML diagram of intermediary pattern 

 

The first step is to create an intermediary

import java.util.Date;
 
public class ChatRoom {
   public static void showMessage(User user, String message){
      System.out.println(new Date().toString()+ " [" + user.getName() +"] : " + message);
   }
}

 The second step is to create objects that require interactive information

public class User {
   private String name;
 
   public String getName() {
      return name;
   }
 
   public User(String name){
      this.name  = name;
   }
 
   public void sendMessage(String message){
      ChatRoom.showMessage(this,message);
   }
}

The third step, the client test

public class Client {
   public static void main(String[] args) {
      User robert = new User("Robert");
      User john = new User("John");
      User bob = new User("bob");
 
      robert.sendMessage("Hi! John!");
      john.sendMessage("Hello! Robert!");
      bob.sendMessage("hello everyone");
   }
}
Tue Apr 07 13:32:17 CST 2020 [Robert] : Hi! John!
Tue Apr 07 13:32:17 CST 2020 [John] : Hello! Robert!
Tue Apr 07 13:32:17 CST 2020 [bob] : hello everyone

Implementation 2

The real intermediary mode is realized with the example of playing cards in real life. There are always wins and losses in playing cards, corresponding to the change of currency. If the intermediary mode is not used, the implementation is as follows

/**
 * 抽象牌友类
 */
public abstract class AbstractCardPartner
{
    double money;

    public void setMoney(double money) {
        this.money = money;
    }

    public abstract void ChangeMoney(int money, AbstractCardPartner other);
}



/**
 * 牌友A
 */
public class PartnerA extends AbstractCardPartner
{

    @Override
    public void ChangeMoney(int money, AbstractCardPartner other) {
        this.money += money;
        other.money -= money;
    }
}




/**
 * 牌友B
 */
public class PartnerB extends AbstractCardPartner
{

    @Override
    public void ChangeMoney(int money, AbstractCardPartner other) {
        this.money += money;
        other.money -= money;
    }
}





import java.io.Console;

/**
 * 客户端测试
 */
public class Client {

    public static void main(String[] args)
    {
        AbstractCardPartner A = new PartnerA();
        A.setMoney(20);
        AbstractCardPartner B = new PartnerB();
        B.setMoney(20);

        // A赢了B的钱减少
        A.ChangeMoney(5, B);
        System.out.println("A 现在的钱是:" + A.money);// 应该是25
        System.out.println("B 现在的钱是:" + B.money);// 应该是15

        // B赢了A的钱减少
        B.ChangeMoney(10, A);
        System.out.println("A 现在的钱是:" + A.money);// 应该是15
        System.out.println("B 现在的钱是:" + B.money);// 应该是25
    }
}

 Test Results:

A 现在的钱是:25.0
B 现在的钱是:15.0
A 现在的钱是:15.0
B 现在的钱是:25.0

Such an implementation does solve the problem in the above scenario, and uses abstract classes to make both concrete player A and player B depend on the abstract class, thereby reducing the coupling between colleagues. However, if the player A changes, it will affect the state of the player B at this time. If more objects are involved, the change of a certain player at this time will affect the state of all other related players. . For example, card player A miscalculated the money. At this time, card player A and card player B have incorrect amounts of money. If more than one person plays cards, the impact will be more. At this time, I will think-can I give the task of calculating money to the program or the person who calculates well? At this time, we have the game of happy landlords in our QQ game.


A further perfect solution is to add an intermediary object to coordinate the association between various objects. This is the application of the intermediary pattern. The specific perfected implementation code is as follows:

The first step is to create an intermediary

/**
 * 中介类,用来处理玩家之间计算金钱的逻辑
 */
public class Mediator
{
    protected AbstractCardPartner a;
    protected AbstractCardPartner b;

    public Mediator(AbstractCardPartner a, AbstractCardPartner b){
        this.a = a;
        this.b = b;
    }

    public void AWin(double money) {
        a.money += money;
        double tmp = b.getMoney() - money;
        b.setMoney(tmp);
    }

    public void BWin(double money) {
        b.money += money;
        double tmp = a.getMoney() - money;
        a.setMoney(tmp);
    }
}

The second step is to create a brand friend

/**
 * 抽象牌友类
 */
public abstract class AbstractCardPartner
{
    double money;

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }

    /**
     * 金钱改变交给中介来处理
     * @param money
     * @param mediator
     */
    public abstract void ChangeMoney(double money, Mediator mediator);
}
/**
 * 牌友A
 */
public class PartnerA extends AbstractCardPartner
{

    @Override
    public void ChangeMoney(double money, Mediator mediator) {
        mediator.AWin(money);
    }
}
/**
 * 牌友B
 */
public class PartnerB extends AbstractCardPartner
{

    @Override
    public void ChangeMoney(double money, Mediator mediator) {
        mediator.BWin(money);
    }
}

The third step, the client test 

import java.io.Console;

/**
 * 客户端测试
 */
public class Client {

    public static void main(String[] args)
    {
        AbstractCardPartner A = new PartnerA();
        A.setMoney(20);
        AbstractCardPartner B = new PartnerB();
        B.setMoney(20);

        Mediator mediator = new Mediator(A,B);

        // A赢了,计算逻辑交给中介者
        A.ChangeMoney(5, mediator);
        System.out.println("A 现在的钱是:" + A.money);// 应该是25
        System.out.println("B 现在的钱是:" + B.money);// 应该是15

        // B赢了,计算逻辑交给中介者
        B.ChangeMoney(10, mediator);
        System.out.println("A 现在的钱是:" + A.money);// 应该是15
        System.out.println("B 现在的钱是:" + B.money);// 应该是25
    }
}
A 现在的钱是:25.0
B 现在的钱是:15.0
A 现在的钱是:15.0
B 现在的钱是:25.0

In the above implementation code, the mediator class saves two abstract cardmate classes. If a new cardmate is added similarly, you will have to change the mediator class at this time. This problem can be solved in conjunction with the observer pattern, that is, the abstract mediator object saves the category of abstract card friends, and then add Register and UnRegister methods to manage the list, and then modify the AWin and BWin methods in the specific mediator class to traverse the list To change the amount of money for yourself and other friends. There is still a problem with this design-that is, when adding a new player, although the problem of no need to modify the abstract intermediary class is solved at this time, it is still necessary to modify the specific intermediary class at this time, that is, add the CWin method, We can use state mode to solve this problem, the introduction of state mode will be introduced in the next article.

The advantages and disadvantages of the intermediary model

advantage:

  • It simplifies the relationship between objects, encapsulates the relationship between the various objects of the system, and decouples the colleagues, making the system loosely coupled.
  • Provides system flexibility, making each colleague object independent and easy to reuse.

Disadvantages:

  • In the intermediary model, the role of the intermediary bears more responsibilities, so if there is a problem with this intermediary object, the entire system will be significantly affected.
  • When a new colleague class is newly added, the abstract mediator class and the concrete mediator class have to be modified. At this time, the observer pattern and state pattern can be used to solve this problem.

Applicable scenarios for intermediary mode

You can consider using the intermediary model in the following situations:

  • A set of well-defined objects, now complex communication with each other.
  • I want to encapsulate the behavior in multiple classes through an intermediate class, but do not want to generate too many subclasses.
Published 138 original articles · praised 34 · 150,000 views

Guess you like

Origin blog.csdn.net/bbj12345678/article/details/105362618