【地铁上的设计模式】--行为型模式:命令模式

2023-05-09 17:52:07 浏览数 (1)

什么是命令模式

命令模式(Command Pattern)是一种行为型设计模式,它将请求(命令)封装成一个对象,以便在不同的上下文中使用,并支持将操作可撤销和重做。该模式的核心思想是将命令的发出者(客户端)和接收者(执行命令的对象)解耦,从而实现请求的发送者和接收者之间的解耦。

命令模式包含以下几个角色:

  • Command(命令接口):声明执行操作的方法。
  • ConcreteCommand(具体命令):将一个 Receiver 对象绑定于一个动作,调用 Receiver 中的相应操作,以实现 execute 方法。
  • Invoker(请求者):调用命令对象执行请求的方法。
  • Receiver(接收者):知道如何实施与执行一个请求相关的操作,任何类都可能作为一个接收者。

命令模式的优点在于:

  • 可以很容易地设计一个命令队列;
  • 可以方便地实现对请求的撤销和恢复;
  • 可以很容易地将命令组合起来,实现批处理等操作;
  • 命令模式是一种类间解耦的设计模式,通过命令对象和接收者的解耦,实现了请求发送者和接收者之间的松耦合,使得系统更加灵活。

命令模式的缺点在于:

  • 实现起来可能需要较多的代码;
  • 使用命令模式可能会增加系统的复杂性;
  • 如果请求的操作有过多的不同种类,则可能需要实现过多的 ConcreteCommand 类。
如何实现命令模式

命令模式的实现步骤如下:

  1. 定义命令接口:定义一个命令接口,该接口包含执行命令和撤销命令两个方法。
  2. 创建具体命令类:实现命令接口,包含一个接收者对象以及执行命令和撤销命令的具体实现。
  3. 创建接收者类:实现命令要调用的方法,是命令实际执行的操作。
  4. 创建调用者类:负责创建具体命令对象并设置接收者对象。
  5. 调用命令:调用者对象调用具体命令对象的执行方法,从而实现对接收者对象的操作。
  6. 撤销命令:调用者对象调用具体命令对象的撤销方法,从而撤销对接收者对象的操作。

以上是命令模式的基本步骤,通过将请求与实现解耦,将请求封装成对象,从而实现了请求的发送者和接收者之间的解耦。

Java实现 以下是一个简单的 Java 实现示例: 首先,我们需要定义命令接口 Command,它包含了执行命令的方法 execute()

代码语言:javascript复制
public interface Command {
    void execute();
}

然后,我们可以定义一些具体的命令类,它们实现了 Command 接口,并实现了对应的业务逻辑。这里我们以打印命令为例:

代码语言:javascript复制
public class PrintCommand implements Command {
    private String message;

    public PrintCommand(String message) {
        this.message = message;
    }

    @Override
    public void execute() {
        System.out.println(message);
    }
}

现在,我们可以定义一个命令调用者类 Invoker,它包含了一个命令列表,并提供了添加和执行命令的方法:

代码语言:javascript复制
import java.util.ArrayList;
import java.util.List;

public class Invoker {
    private List<Command> commandList = new ArrayList<>();

    public void addCommand(Command command) {
        commandList.add(command);
    }

    public void executeCommands() {
        for (Command command : commandList) {
            command.execute();
        }
        commandList.clear();
    }
}

最后,我们可以定义一个客户端类 Client,它用来创建具体的命令对象并将它们添加到 Invoker 中:

代码语言:javascript复制
public class Client {
    public static void main(String[] args) {
        Invoker invoker = new Invoker();
        Command command1 = new PrintCommand("Command 1 executed.");
        Command command2 = new PrintCommand("Command 2 executed.");
        invoker.addCommand(command1);
        invoker.addCommand(command2);
        invoker.executeCommands();
    }
}

这里的 Client 类创建了两个具体的命令对象,并将它们添加到 Invoker 中,最后执行了这些命令。

C#实现 以下是 C# 实现命令模式的示例代码:

代码语言:javascript复制
// 命令接口
public interface ICommand
{
    void Execute();
}

// 接收者
public class Receiver
{
    public void Action()
    {
        Console.WriteLine("Receiver Action");
    }
}

// 具体命令类
public class ConcreteCommand : ICommand
{
    private Receiver receiver;

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

    public void Execute()
    {
        receiver.Action();
    }
}

// 调用者
public class Invoker
{
    private ICommand command;

    public void SetCommand(ICommand command)
    {
        this.command = command;
    }

    public void ExecuteCommand()
    {
        command.Execute();
    }
}

其中,ICommand 是命令接口,定义了 Execute() 方法用于执行命令。Receiver 是接收者,具体实现了命令的真正执行过程。ConcreteCommand 是具体的命令类,包含了一个接收者对象,调用其 Action() 方法实现命令执行。Invoker 是调用者,负责接收命令,并执行命令。在 ExecuteCommand() 方法中,调用 command.Execute() 实现命令的执行。

总结

命令模式是一种行为型设计模式,其目的是将一个请求封装为一个对象,从而使不同的请求可以被多个对象处理。命令模式中包含三种主要角色:命令接口、具体命令和命令执行者。 命令接口规定了命令的公共接口,具体命令则实现了命令接口并包含了具体的操作逻辑。命令执行者是真正执行命令的对象,它包含了一些执行命令所需的上下文信息,例如命令的参数、命令的执行时间等。 命令模式的优点是可以解耦命令发送者和命令执行者,从而使得系统更加灵活。此外,命令模式还支持撤销和重做操作,能够提高系统的可维护性和可扩展性。 命令模式的缺点在于会增加系统的复杂性,增加了命令对象的数量,同时也会增加代码的复杂性。此外,命令模式在某些场景下也可能会造成性能问题,例如需要执行大量的命令时。 总之,命令模式是一种非常实用的设计模式,适用于需要将请求和处理对象解耦的场景。在实现命令模式时需要权衡复杂性和灵活性,并考虑系统的性能和可维护性。

0 人点赞