Design Mode | Command Mode (Command)

definition:

Encapsulate a request as an object, so that you can parameterize customers with different requests; queue requests or record request logs, and support reversible operations.

Structure: (picture in the book, intrusion and deletion)

 

An abstract command class

Several specific command classes

Recipient classes for certain specific execution orders

An Invoker

There is no client class, all requests are made directly through the message class

 

Examples:

When it comes to orders, I think of the emperor, and then think of usually more than one customer, but the emperor has only one, but it is not important, the point is not here.

The emperor’s orders are usually directly told to the eunuch chiefs around him that he will not find someone to give orders in person, and he may not really know the eunuch maids underneath.

so... Command mode is also suitable here.

I made some changes, first paste the code and then elaborate.

 Palace girls (recipient):

package designpattern.command;

/*
 * 宫女
 */
public class Maid {
    String name;

    public Maid(String name) {
        this.name = name;
    }

    public void clean() {
        System.out.println(this.name + ":打扫卫生");
    }
}

Eunuch (recipient):

package designpattern.command;

/*
 * 太监
 */
public class Eunuch {
    String name;

    public Eunuch(String name) {
        this.name = name;
    }

    public void carrySedanChair() {
        System.out.println(this.name + ":抬轿子");
    }
}

Abstract command interface:

package designpattern.command;

public interface Command {
    public void execute();
}

Cleaning command class (specific command class):

package designpattern.command;

public class CleanCommand implements Command {
    private Maid maid;

    public CleanCommand(Maid maid) {
        this.maid = maid;
    }

    @Override
    public void execute() {
        maid.clean();
    }

}

Sedan lift command class (specific command class):

package designpattern.command;

public class CarrySedanChairCommand implements Command {
    private Eunuch eunuch;

    public CarrySedanChairCommand(Eunuch eunuch) {
        this.eunuch = eunuch;
    }

    @Override
    public void execute() {
        eunuch.carrySedanChair();

    }
}

Eunuch chief (Invoker):

package designpattern.command;

import java.util.ArrayList;
import java.util.List;

public class ManagerEunuch {
    private List<Command> commands = new ArrayList<Command>();

    public void setCommand(Command command) {
        this.commands.add(command);
    }

    public void notifyIt() {
        for (Command command : commands) {
            command.execute();
        }
    }
}

Client:

package designpattern.command;

public class Client {
    public static void main(String[] args) {
        Maid xiaocui = new Maid("小翠");
        Maid xiaohua = new Maid("小花");
        Eunuch xiaozhuozi = new Eunuch("小卓子");
        Eunuch xiaoguizi = new Eunuch("小贵子");

        Command cleanCommand1 = new CleanCommand(xiaocui);
        Command cleanCommand2 = new CleanCommand(xiaohua);

        Command carrySedanChairCommand1 = new CarrySedanChairCommand(xiaozhuozi);
        Command carrySedanChairCommand2 = new CarrySedanChairCommand(xiaoguizi);

        ManagerEunuch ligongong = new ManagerEunuch();
        ligongong.setCommand(cleanCommand1);
        ligongong.setCommand(cleanCommand2);
        ligongong.setCommand(carrySedanChairCommand1);
        ligongong.setCommand(carrySedanChairCommand2);
        ligongong.notifyIt();

    }
}

Result output:

Komidori: cleaning 
flowers: cleaning 
small zhuozi: sedan chair 
small Takako: sedan chair

 

I originally thought that there should be many kinds of receivers for orders. For example, in my example, there are court ladies and eunuchs. But my actual feeling is that this is more suitable for a single executor.

Although I have implemented multiple executors, the executors and specific commands are deeply coupled. For example, the cleaning command (CleanCommand) has an instance of the court lady (executor).

If the eunuch wants to clean, you must create another cleaning command class with an instance of the eunuch. Although you can abstract an executor parent class and let them all hold instances of this parent class, you cannot call father.clean(), Unless you define this method in the parent class, but whenever the child class adds a method, the parent class must increase accordingly, which is obviously not a good design. I haven't thought of a good way to solve this problem for the time being, so I think it may be more suitable for a single type of performer.

emmm, I just thought about it again. It may be that there is a problem with the classification of executors in my example. It may be that the scope of work of each executor is quite different. For example, in my example, there may be 50% of palace ladies and eunuchs. The jobs are overlapped. If we classify them by specific types of jobs, such as those in the imperial dining room and the laundry room, then there will be no problem. It can be regarded as a misunderstanding of thinking. learn a lesson.

 

to sum up:

I think the points written in the book are quite good, so let's quote them here.

First, it can easily design a command queue;

Second, it is easier to log commands when needed;

Third, allow the party receiving the request to decide whether to reject the request

Fourth, you can easily cancel and redo the request;

Fifth, because adding a new specific command class does not affect other classes, it is easy to add a new specific command class.

The key advantage is that the command mode separates the object that requests an operation from the object that knows how to perform an operation.

Guess you like

Origin blog.csdn.net/a159357445566/article/details/109266636