The Command Pattern is a behavioral design pattern that turns a request into a stand-alone object. This object contains all information about the request. This transformation allows you to parameterize methods with different requests, delay or queue a request's execution, and support undoable operations. It's a part of the larger family of design patterns often utilized in software development for organizing code in a way that is both flexible and scalable.
命令模式是一种行为设计模式,它将请求转化为一个独立的对象。该对象包含请求的所有信息。通过这种转换,您可以为具有不同请求的方法设置参数,延迟或排队执行请求,并支持可撤消(undo)的操作。它是软件开发中常用的大型设计模式系列的一部分,用于以灵活和可扩展的方式组织代码。

Participants 参与者

  • Command: This is an interface or an abstract class that defines the method execute() for executing the commands. It might also include an undo() method to reverse the command's action.
  • ConcreteCommand: Implements the Command interface and defines the binding between a Receiver object and an action. The ConcreteCommand object invokes the action on the Receiver when the Command's execute() method is called.
  • Client: The client object creates a ConcreteCommand object and sets its receiver.
  • Invoker: Asks the command to carry out the request.
  • Receiver: Knows how to perform the operations associated with carrying out a request. Any class can serve as a Receiver.

Sample Code

public interface Command {
    void execute();
}

LightOnCommand是具体的命令(Concrete Command)

public class LightOnCommand implements Command {
    Light light;

    public LightOnCommand(Light light) {
        this.light = light;
    }

    @Override
    public void execute() {
        light.on();
    }
}

其中Light是接收者(Receiver)

public class Light {
    String location;
    int level;

    public Light(){}

    public Light(String location) {
        this.location = location;
    }

    public void on() {
        level = 100;
        System.out.println("Light is on");
    }

    public void off() {
        level = 0;
        System.out.println("Light is off");
    }

    public void dim(int level) {
        this.level = level;
        if (level == 0) {
            off();
        }
        else {
            System.out.println("Light is dimmed to " + level + "%");
        }
    }

    public int getLevel() {
        return level;
    }
}

SimpleRemoteControl是调用者(Invoker)

public class SimpleRemoteControl {
    /**
     * Slot 插槽
     */
    Command slot;

    public SimpleRemoteControl(){}

    public void setCommand(Command command) {
        slot = command;
    }

    public void buttonWasPressed() {
        slot.execute();
    }
}

RemoteControlTest是客户(Client)

// Test 类是客户
public class RemoteControlTest {
    public static void main(String[] args) {
        /*
        * 遥控器是调用者
        * 会被传入一个可以用来做出请求的命令对象
        * */
        SimpleRemoteControl remote = new SimpleRemoteControl();
        /*
        * Light 对象,请求的接收者
        * */
        Light light = new Light();
        /*
        * 命令对象
        * 创建一条命令并把接收者传给它
        * */
        LightOnCommand lightOn = new LightOnCommand(light);
        /*
        * 把命令传给调用者
        * */
        remote.setCommand(lightOn);
        remote.buttonWasPressed();
    }
}

Defined

The Command Pattern encapsulates a request as an object, thereby letting you parameterize other objects with different requests, queue or log requests, and support undoable operations.
命令模式把请求封装为对象,以便用不同的请求、队列或者日志请求来参数化其他对象,并支持可撤销操作。

命令对象(LightOnCommand)通过在特定接收者(Light)上绑定一组动作来封装请求:

public class LightOnCommand implements Command {
    Light light;

    public LightOnCommand(Light light) {
        this.light = light;
    }

    @Override
    public void execute() {
        light.on();
    }
}

它把动作和接收者包进一个对象中,该对象只暴露一个方法,execute()就如上面的代码一样。当被调用时,execute()引起接收者上的动作被调用(light.on())。从外面看,没有其他对象真正知道什么接收者执行了什么动作,只知道如果调用execute()方法,请求的目的就能达到了。

Structure

command_pattern.png

命令模式的更多用途:

  • 请求队列
  • 日志请求

Create with GPT-4

标签: none

评论已关闭