Command mode & mediator mode

With feelings and dry goods, wechat search [Third Prince Ao Bing] pays attention to this programmer with a little something.

This article GitHub https://github.com/JavaFamily It has been included. There are complete test sites, materials and my series of articles for the interview of front-line large factories.

Recently, I was sharing a series of articles on design patterns with you. A younger sister asked me, what are the differences among command pattern, strategy pattern and factory pattern? It doesn't make any difference to see the implementation of the code?

We have shared the strategy mode and factory mode with you before. Interested students can review it again. Today, we will focus on the analysis of command mode, and then look at the difference between them?

Previous review:

Command mode

definition
  • Provide a unified method to encapsulate commands, and judge what command actions to execute through parameter conditions.
  • Allows each command to be stored in a queue.

The overall structure diagram is as follows:

Explanation of important roles in the structure diagram:

  • Command: defines the abstract encapsulation class of the command.
  • ConcreteCommand (concrete Command class): implement the Command class, which is the actual implementation class of the specific Command.
  • Receiver: the operation class associated with the execution command.
  • Invoker: trigger command class, that is, external operation events trigger execution.
  • Client: instantiate the specific command object and the actual class of the receiver.

In fact, the whole structure seems difficult to understand, but since you are learning design patterns, you must understand each design pattern to improve your knowledge

In order to deepen understanding, I would like to give a good example:

You must be familiar with the ancient Chinese monarchy. The emperor could ask his father-in-law to receive or distribute memorials. In fact, I personally feel that this can reflect the command mode.

The father-in-law is equivalent to the receiver of the command mode, executing the emperor's order, collecting the early Dynasty Memorial (ConcreteCommand) or issuing the concretecommand

The emperor is equivalent to the invoker of the command mode

Old rules, finish the example and look at the code

// Define command class
public interface Command {
    // Method of execution
    void execute();
}

// Define the role of receiver father-in-law
public class Receiver {

    public void Charge(){
        System.out.println("Collect memorials");
    }

    public void Issue(){
        System.out.println("Issue an edict");
    }
}


//The specific command class is one, and the memorial command is received
public class ConcreteCommandOne implements Command {

    // Receiver, here can be understood as father-in-law
    private Receiver receiver;

    public ConcreteCommandOne(Receiver receiver) {
        this.receiver = receiver;
    }

    @Override
    public void execute() {
        // Collect memorials
        receiver.Charge();
    }
}

// Specific orders two, issue the edict
public class ConcreteCommandTwo implements Command {

    // Receiver, here can be understood as father-in-law
    private Receiver receiver;

    public ConcreteCommandTwo(Receiver receiver) {
        this.receiver = receiver;
    }

    @Override
    public void execute() {
        // Issue an edict
        receiver.Issue();
    }
}

// Caller, Emperor
public class Invoker {
  
    private Command command;

    public Invoker(Command command) {
        this.command = command;
    }
    // Commands to be executed this time
    public void action() {
        command.execute();
    }
}

	// Test demo
    public static void main(String[] args) {
        // Instantiate a public receiver
        Receiver receiver =new Receiver();
        // How many commands can father-in-law receive at present
        Command commandOne = new ConcreteCommandOne(receiver);
        Command commandTwo = new ConcreteCommandTwo(receiver);

        // The execution method triggered by the emperor's command
        Invoker invoker =new Invoker(commandOne);
        invoker.action();
        // result: collect memorials

        Invoker invokerTwo =new Invoker(commandTwo);
        invokerTwo.action();
        // result: promulgate the edict
    }

The above is a simple code implementation. Through the choice of Invoker, the Receiver can determine what command to execute. This is actually a simple embodiment of the command mode.

Careful students don't know if they have found a problem in the definition

  • Allows each command to be stored in a queue.

There is no queue here. In fact, this implementation is also very simple. Just add a queue in the main method

    public static void main(String[] args) {
        // Instantiate a public receiver
        Receiver receiver = new Receiver();
        // How many commands can father-in-law receive at present
        Command commandOne = new ConcreteCommandOne(receiver);
        Command commandTwo = new ConcreteCommandTwo(receiver);
				// Store command
        Queue<Command> queue = new LinkedList<>();
        queue.add(commandOne);
        queue.add(commandTwo);
				// Batch execution
        for (Command command : queue) {
            Invoker invoker = new Invoker(command);
            invoker.action();
        }
    }

Here I want to make an extension point for you, which is also a verification writing method I have seen before.

In real work, you will certainly encounter a lot of interface verification. How to write this verification logic and how to reuse and abstract the code is actually a difficult problem!

Let's take a general look at the structure diagram!!!

I also write the demo code for you. It should be noted that we need to implement the afterpropertieset method in ApplicationContextAware.

// Define abstract verification methods
public abstract class ValidatePlugin {
    public abstract void validate();
}
// Abstract rule executor
public abstract class ValidatePluginExecute {
    protected abstract List<ValidatePlugin> getValidatePlugins();
    public void execute() {
        final List<ValidatePlugin> validatePlugins = getValidatePlugins();
        if (CollectionUtils.isEmpty(validatePlugins)) {
            return;
        }
        for (ValidatePlugin validatePlugin : validatePlugins) {
          // Execute the verification logic, where you can modify according to your actual business scenario
            validatePlugin.validate();
        }
    }
}

// Specific test rules
@Component("validatePluginOne")
public class ValidatePluginOne extends  ValidatePlugin {
    @Override
    public void validate() {
        System.out.println("validatePluginOne Rule verification");
    }
}

// The specific executor adds the rules to be executed to validatePlugins
@Component("testValidatePlugin")
public class TestValidatePlugin extends ValidatePluginExecute implements ApplicationContextAware, InitializingBean {

    protected ApplicationContext applicationContext;

    private List<ValidatePlugin> validatePlugins;

    @Override
    public void afterPropertiesSet() {
      // Add rule
        validatePlugins = Lists.newArrayList();
        validatePlugins.add((ValidatePlugin) this.applicationContext.getBean("validatePluginOne"));

    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Override
    protected List<ValidatePlugin> getValidatePlugins() {
        return this.validatePlugins;
    }
}

// Test demo
  public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
        TestValidatePlugin testValidatePlugin = (TestValidatePlugin) applicationContext.getBean("testValidatePlugin");
        testValidatePlugin.execute();
    }

This is just a simple test demo. In order to make everyone think, the design pattern does not necessarily copy the code. More is to broaden their horizons and improve their ability to solve problems.

For different interfaces, we only need to add specific verification rules in TestValidatePlugin. The overall scalability becomes higher and looks tall.

So what is the difference between the command mode, policy mode and factory mode mentioned above?

  • Command mode: it belongs to behavioral design mode. In command mode, different commands will produce different purposes and results during execution, and different commands cannot be replaced.

  • Policy mode: it is a behavioral design mode. In the policy mode, the focus is on the implementation of each policy and solving the problem of selecting different policies from a group of policies according to the runtime state

  • Factory mode: it belongs to the creation design mode. In the factory mode, the focus is on the creation process of encapsulated objects. The objects here are not limited by any business scenario. They can be policies, but they can also be other things

Therefore, for design patterns, what I understand is only one problem. Different design patterns are designed to deal with different scenarios, and different business scenarios have different writing methods.

Intermediary model

The intermediary model can also be understood from the name. An intermediate structure is established to facilitate the management of downstream organizations.

So what is the mediation model?

It is explained in the design pattern in GoF that the mediation pattern defines a single (mediation) object to encapsulate the interaction between a group of objects. Delegate the interaction between this group of objects to the interaction with mediation objects to avoid direct interaction between objects.

Let's take another look at the structure diagram:

  • Mediator (Abstract mediator): used to define the interaction between participants and mediators

  • Concrete mediator: implements the operations defined by the mediator, that is, the interaction mode.

  • Collage (Abstract Colleague role): abstract class or interface, which is mainly used to define how participants interact.

  • Concretecollage (with Colleague role): it is very simple, which is to implement the methods in collage.

    The above structure definition comes from the beauty of design pattern

Looking at this structure chart, I can understand that it is actually a little the same as the observer model written for you before. Interested students can review it again.

Old rules, or specific examples of code implementation

The high-speed railway system should be clear that there is a dispatching center to control the arrival sequence of each high-speed railway. If there is no such dispatching center, when three high-speed railways are about to enter the station at the same time, they need two-way communication. If one of the bullet trains is not communicated, an immeasurable error will occur. Therefore, it is necessary to handle the communication logic through the dispatching center and manage how many vehicles are waiting to enter the station.

// Abstract participants can also be written in abstract
public interface Colleague {
  	// Communication message
    void message();
}
// Abstract mediator
public interface Mediator {
    // Define processing logic
    void doEvent(Colleague colleague);
}

// Specific participants
@Component
public class MotorCarOneColleague implements Colleague {

    @Override
    public void message() {
        // Analog processing business logic
        System.out.println("HS1 received the message!!!");
    }
}
@Component
public class MotorCarTwoColleague implements Colleague {
    @Override
    public void message() {
        System.out.println("HS2 received the message!!!");
    }
}
@Component
public class MotorCarThreeColleague implements Colleague {
    @Override
    public void message() {
        System.out.println("HS3 received the message!!!");
    }
}

// Specific intermediary
@Component
public class DispatchCenter implements Mediator {
  // Who are the participants in the management
    @Autowired
    private List<Colleague> colleagues;
  
    @Override
    public void doEvent(Colleague colleague) {
        for(Colleague colleague1 :colleagues){
            if(colleague1==colleague){
                // If it is high-speed railway information, it can process other business logic
                // doSomeThing();
                continue;
            }
          // Notify other participants
            colleague1.message();
        }
    }
}

// Test demo
public static void main(String[] args) {
  			// Initialize spring container
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
  			// Get broker, dispatch center
        DispatchCenter dispatchCenter = (DispatchCenter) applicationContext.getBean("dispatchCenter");


        // High speed rail No. 1 sends a message
        MotorCarOneColleague motorCarOneColleague =  (MotorCarOneColleague) applicationContext.getBean("motorCarOneColleague");
  			// Communicate information through dispatching center
        dispatchCenter.doEvent(motorCarOneColleague);
        // result: HS3 received the message!!!
        //         HS2 received the message!!!


        // High speed rail No. 2 sends a message
        MotorCarTwoColleague  motorCarTwoColleague = (MotorCarTwoColleague)applicationContext.getBean("motorCarTwoColleague");
        dispatchCenter.doEvent(motorCarTwoColleague);
        // result: HS1 received the message!!!
        //         HS3 received the message!!!

    }

Even if the mediator mode demo code is completed, you should be able to find that the mediator is still well understood through this demo.

However, the application scenario of intermediaries is still relatively rare. For some classes that are heavily dependent and form a similar network structure, it is changed into a structure similar to dandelion, which diffuses from the middle to the outside to achieve the effect of decoupling.

More are common in a UI interface control, of course, in Java util. Timer can also be understood as mediator mode, because it can control how internal threads run, such as how often they run.

The mediator and observer patterns mentioned above are very similar, and you can also find this through the demo code

In the observer mode, the observer and the observed are basically fixed, while in the mediator mode, the observer and the observed are not fixed, and the mediator may eventually become a huge primitive class.

summary

Command mode: although it is not very common, we still need to distinguish it from factory mode and policy mode, what is the application scenario and what thinking it can bring us.

For example, in my last example, the command mode can store commands. The essence is to maintain commands in a queue. Why can't we also maintain some interface verification dependencies through an array in our business code, which stores bean instances that need verification. To improve the reusability and scalability of the code.

Mediation mode: on the whole, it is less applied. Although it can decouple objects, it also has side effects. In addition, we rarely encounter such scenarios in our real business scenarios. Just learn about the implementation principle. As for the difference from the observer, it is also mentioned above, More, we may already be using some middleware message queues to process.

I'm Ao Bing. The more you know, the more you don't know. I'll see you next time!!!

Ao Bing organized his interview articles into an e-book, a total of 1630 pages!

Full of dry goods, the essence of every word. The table of contents is as follows, as well as the interview questions and resume templates summarized during my review. Now I give them to you for free.

Link: https://pan.baidu.com/s/1ZQEKJBgtYle3v-1LimcSwg Password: wjk6

I'm Ao Bing. The more you know, the more you don't know. Thank you for your praise, collection and comments. See you next time!

The article is continuously updated. You can search "three Prince Ao Bing" on wechat, read it for the first time, and reply to [data] there are the interview data and resume template of front-line large factories prepared by me. This article GitHub https://github.com/JavaFamily It has been included. There are complete test sites for large factory interviews. Welcome Star.

Keywords: Design Pattern

Added by dibyendrah on Tue, 18 Jan 2022 10:30:22 +0200