软件设计模式系列之十六——命令模式

软件设计,模式,系列,十六,命令 · 浏览次数 : 46

小编点评

**命令模式**是一种行为型设计模式,用于将请求封装成对象,并允许客户端通过调用对象的方法执行请求。 **核心思想:** * 将请求封装成一个对象,包括请求的参数和接收者对象。 * 客户端只需调用对象的方法来执行命令,而不需要关心请求的具体细节。 * 支持撤销和重做操作。 **结构命令模式的结构:** * **Command** 接口定义一个执行操作的接口,包括 `execute` 方法。 * **ConcreteCommand** 类实现命令接口,绑定接收者对象。 * **Receiver** 类负责执行与请求相关的具体操作。 * **Invoker** 类负责将命令对象传递给接收者执行命令。 **代码实现:** ```java // Command 接口 public interface Command { void execute(); } // ConcreteCommand 类实现 Command 接口,绑定接收者 public class LightOnCommand implements Command { private Light light; public LightOnCommand(Light light) { this.light = light; } @Override public void execute() { light.turnOn(); } } // Receiver 类负责执行与请求相关的具体操作 public class Light { public void turnOn() { System.out.println("Light is on"); } } // Invoker 类负责将命令对象传递给接收者执行命令 public class RemoteControl { private Command command; public void setCommand(Command command) { this.command = command; } public void pressButton() { command.execute(); } } // 客户端代码 public class Client { public static void main(String[] args) { // 创建接收者对象 Light light = new Light(); // 创建具体命令对象并关联接收者 LightOnCommand lightOnCommand = new LightOnCommand(light); // 创建调用者 RemoteControl remoteControl = new RemoteControl(); // 设置命令并执行 remoteControl.setCommand(lightOnCommand); remoteControl.pressButton(); } } ``` **优点:** * 解耦请求的发送者和接收者。 * 支持撤销和重做操作。 * 提供扩展性和灵活性。 **缺点:** * 可能导致命令类膨胀。 * 不适用于所有场景。

正文

1 模式的定义

命令模式(Command Pattern)是一种行为型设计模式,旨在将请求发送者和接收者解耦,将一个请求封装为一个对象,从而允许您参数化客户端对象以进行不同的请求、排队请求或记录请求,并支持可撤销操作。

命令模式的核心思想是将一个请求包装成一个对象,包括请求的参数和接收者对象,然后客户端只需要调用该对象的方法来执行请求,而不需要关心请求的具体细节。这种方式使得请求的发送者和接收者之间的关系变得松耦合,同时支持一些附加功能,如命令的撤销和重做。

2 举例说明

为了更好地理解命令模式,让我们考虑一个实际的例子:遥控器控制家电。假设您有一个遥控器,可以控制不同种类的家电设备,如电视、音响和灯。每个按钮都代表一个命令,例如打开电视、关闭音响、调暗灯光等。命令模式可以用于实现这种遥控器系统。

在这个例子中,每个命令(如打开电视)都被封装成一个命令对象,包括具体的操作(执行命令)和接收者对象(执行命令的设备)。遥控器上的按钮只需要关联一个命令对象,并在按下按钮时执行该命令。这种方式使得遥控器可以轻松控制不同种类的家电设备,而不需要关心它们的具体实现。

3 结构

命令模式的结构包括以下几个关键部分:

Command(命令):定义一个执行操作的接口,通常包括一个 execute 方法,负责执行具体的命令。

ConcreteCommand(具体命令):实现命令接口,将一个接收者对象绑定到一个操作。它负责调用接收者的方法来执行命令。

Receiver(接收者):负责执行与请求相关的具体操作,是命令真正的执行者。

Invoker(调用者):负责将命令对象传递给接收者执行命令,它不需要知道命令的具体细节,只需调用命令的 execute 方法即可。

Client(客户端):创建具体命令对象,并将命令对象与接收者对象关联,然后将命令对象传递给调用者来执行。

4 实现步骤

实现命令模式时,通常遵循以下步骤:

定义命令接口(Command),其中包括一个 execute 方法用于执行命令。

创建具体命令类(ConcreteCommand),实现命令接口,并在构造函数中绑定一个接收者对象。

定义接收者类(Receiver),负责执行具体的操作。

创建调用者类(Invoker),负责接收命令对象并执行命令。

在客户端中创建命令对象和接收者对象,并将它们关联。然后将命令对象传递给调用者,由调用者执行命令。

5 代码实现

现在,让我们通过 Java 代码来实现上述遥控器控制家电的命令模式。

// 1. 定义命令接口
interface Command {
    void execute();
}

// 2. 创建具体命令类
class LightOnCommand implements Command {
    private Light light;

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

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

class LightOffCommand implements Command {
    private Light light;

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

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

// 3. 定义接收者类
class Light {
    public void turnOn() {
        System.out.println("Light is on");
    }

    public void turnOff() {
        System.out.println("Light is off");
    }
}

// 4. 创建调用者类
class RemoteControl {
    private Command command;

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

    public void pressButton() {
        command.execute();
    }
}

// 5. 客户端代码
public class Client {
    public static void main(String[] args) {
        // 创建接收者对象
        Light light = new Light();

        // 创建具体命令对象并关联接收者
        Command lightOn = new LightOnCommand(light);
        Command lightOff = new LightOffCommand(light);

        // 创建调用者
        RemoteControl remote = new RemoteControl();

        // 设置命令并执行
        remote.setCommand(lightOn);
        remote.pressButton();

        remote.setCommand(lightOff);
        remote.pressButton();
    }
}

6 典型应用场景

命令模式在实际应用中有多种典型场景,包括但不限于:

遥控器控制:如上面的示例所示,可以用命令模式实现遥控器来控制不同的家电设备,如电视、音响和灯。

文本编辑器操作:文本编辑器中的撤销、重做、剪切、复制、粘贴等操作可以使用命令模式来实现。

菜单系统:图形用户界面(GUI)应用中的菜单项和按钮操作可以通过命令模式来处理。

游戏中的动作:在游戏中,角色的动作和命令(如攻击、防御、跳跃等)可以使用命令模式来处理。

多级撤销操作:命令模式支持撤销和重做操作,因此在需要多级撤销的应用中很有用,如图像编辑器或CAD软件。

日程安排应用:在日程安排应用中,可以使用命令模式来处理添加、编辑、删除事件等操作。

7 优缺点

优点:

解耦发送者和接收者:命令模式将请求的发送者和接收者解耦,发送者不需要知道接收者的具体实现,从而降低了系统的耦合度。

支持撤销和重做:命令模式可以轻松支持命令的撤销和重做,因为每个命令对象都包含了执行和撤销操作的逻辑。

支持扩展:可以轻松添加新的命令和接收者,而无需修改现有的客户端代码。

支持排队请求:命令模式允许将请求排队,以便按照先后顺序执行,或者实现任务调度。

缺点:

可能导致命令类膨胀:如果有大量的命令操作,可能会导致命令类的膨胀,增加维护的复杂性。

不适用于所有情况:命令模式不适用于所有场景,特别是对于简单的命令,直接调用方法可能更加简单和高效。

增加代码复杂性:引入命令模式会增加一定的代码复杂性,因为需要创建额外的命令类和接收者类。

8 类似模式

策略模式(Strategy Pattern):策略模式也可以用于封装可互换的行为,但它的主要目的是在运行时选择算法或策略,而不是将请求封装成命令对象。

观察者模式(Observer Pattern):观察者模式用于定义对象之间的一对多依赖关系,当一个对象状态发生变化时,所有依赖于它的对象都会收到通知。与命令模式不同,观察者模式不涉及命令的封装和执行。

中介者模式(Mediator Pattern):中介者模式用于减少对象之间的直接耦合,将对象之间的通信集中在一个中介者对象中。与命令模式不同,中介者模式通常用于管理对象之间的交互,而不是将请求封装成命令。

9 小结

命令模式是一种有用的设计模式,它允许将请求封装成命令对象,从而解耦请求的发送者和接收者,支持撤销和重做操作,并提供扩展性和灵活性。命令模式在实际应用中有多种典型场景,包括遥控器控制、文本编辑器操作、菜单系统等。虽然命令模式增加了一些复杂性,但它可以提高代码的可维护性和可扩展性,是面向对象设计中的重要模式之一。

与软件设计模式系列之十六——命令模式相似的内容:

软件设计模式系列之十六——命令模式

命令模式(Command Pattern)是一种行为型设计模式,旨在将请求发送者和接收者解耦,将一个请求封装为一个对象,从而允许您参数化客户端对象以进行不同的请求、排队请求或记录请求,并支持可撤销操作。 命令模式的核心思想是将一个请求包装成一个对象,包括请求的参数和接收者对象,然后客户端只需要调用该...

软件设计模式系列之十一——装饰模式

装饰模式属于结构型设计模式,它通过将对象包装在装饰器类中来动态地添加额外的行为,而不需要修改原始对象的代码。这个模式以透明的方式向对象添加功能,从而使您可以根据需要组合各种功能。

软件设计模式系列之十二——外观模式

外观模式是一种结构型设计模式,它提供了一个简化的接口,用于访问系统中的一组相关接口,以隐藏系统的复杂性。外观模式的主要目标是简化客户端与子系统之间的交互,同时降低了系统的耦合度。它允许客户端通过一个统一的入口点来与系统进行通信,而不需要了解系统内部的具体细节和复杂性

软件设计模式系列之十三——享元模式

享元模式(Flyweight Pattern)是一种结构型设计模式,它旨在减少内存占用或计算开销,通过共享大量细粒度对象来提高系统的性能。这种模式适用于存在大量相似对象实例,但它们的状态可以外部化(extrinsic),并且可以在多个对象之间共享的情况。

软件设计模式系列之十四——代理模式

代理模式是一种结构型设计模式,它允许一个对象(代理)充当另一个对象的接口,以控制对该对象的访问。代理模式通常用于控制对真实对象的访问,以实现一些额外的功能,例如延迟加载、权限控制、日志记录等。这种模式属于结构型设计模式,因为它关注对象之间的组合,以形成更大的结构。

软件设计模式系列之十九——中介者模式

@目录1 模式的定义2 举例说明3 结构4 实现步骤5 代码实现6 典型应用场景7 优缺点8 类似模式9 小结 1 模式的定义 中介者模式是一种行为型设计模式,它用于降低对象之间的直接通信,通过引入一个中介者对象来管理对象之间的交互。这种模式有助于减少对象之间的耦合性,使系统更加可维护和扩展。中介者

软件设计模式系列之十八——迭代器模式

迭代器模式是一种行为型设计模式,它允许客户端逐个访问一个聚合对象中的元素,而不暴露该对象的内部表示。迭代器模式提供了一种统一的方式来遍历不同类型的集合,使客户端代码更加简洁和可复用。

软件设计模式系列之十七——解释器模式

解释器模式是一种行为型设计模式,它用于将一种语言或表达式解释为对象。该模式通过定义语言的文法规则,并使用解释器来解释和执行这些规则,将复杂的语言转换为对象的操作。 在软件开发中,解释器模式常用于处理类似于编程语言、查询语言、正则表达式等需要解释和执行的场景。它将一个复杂的语言分解为一系列简单的规则,...

软件设计模式系列之十五——职责链模式

职责链模式(Chain of Responsibility Pattern)也称为责任链模式,是一种结构型设计模式,用于构建一条对象处理请求的责任链。在这个模式中,多个对象依次处理请求,直到其中一个对象能够处理该请求为止。职责链模式将请求的发送者和接收者解耦,允许多个对象都有机会处理请求,同时可以动...

软件设计模式系列之十——组合模式

组合模式是一种结构型设计模式,用于将对象组合成树形结构以表示部分-整体层次结构。这个模式允许客户端以一致的方式处理单个对象和对象组合,因此它将单个对象和组合对象视为可互换的。 组合模式允许你将对象组合成树状结构来表示"部分-整体"的层次结构。组合模式使得客户端可以统一地处理单个对象和组合对象,无需关...