行为型模式-命令模式

发布时间 2023-11-10 16:54:37作者: Qt小罗

1 什么是命令模式

命令模式(Command Pattern)是一种行为型设计模式,它将请求封装成一个对象,从而可以使用不同的请求参数、对请求排队或记录请求日志,以及支持可撤销的操作。

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

  • 命令(Command):声明执行操作的接口,通常包含一个执行方法(execute)。
  • 具体命令(Concrete Command):实现命令接口,负责执行具体的操作。它包含了接收者(Receiver)对象,通过调用接收者的方法来执行操作。
  • 接收者(Receiver):执行具体操作的对象。
  • 调用者(Invoker):调用命令对象来执行请求,它不能直接与接收者交互,而是通过命令对象间接地调用接收者。
  • 客户端(Client):创建命令对象、配置命令对象和接收者之间的关系,并将命令对象传递给调用者。

2 举个例子

下面以一个简单的遥控器程序为例来说明命令模式的应用。假设我们有一个遥控器,希望能够通过按下不同的按钮来执行不同的操作,比如打开电灯、关掉电视等。

首先,我们定义命令接口 Command,其中声明了执行操作的方法 execute:

class Command {
public:
    virtual void execute() = 0;
    virtual ~Command() {}
};

然后,我们创建具体命令类,比如打开电灯命令类、关掉电视命令类等,它们实现了命令接口,并包含了执行具体操作的逻辑:

class LightOnCommand : public Command {
private:
    Light& light;

public:
    LightOnCommand(Light& light) : light(light) {}

    void execute() override {
        light.on();
    }
};

class TVOffCommand : public Command {
private:
    TV& tv;

public:
    TVOffCommand(TV& tv) : tv(tv) {}

    void execute() override {
        tv.off();
    }
};

接着,我们定义接收者类,比如电灯类和电视类,它们包含了具体的操作方法:

class Light {
public:
    void on() {
        cout << "Light is on." << endl;
    }

    void off() {
        cout << "Light is off." << endl;
    }
};

class TV {
public:
    void on() {
        cout << "TV is on." << endl;
    }

    void off() {
        cout << "TV is off." << endl;
    }
};

在调用者类中,我们创建了一个按钮对象,并将具体的命令对象与按钮关联起来,以实现将按钮按下时的操作:

class Button {
private:
    Command& command;

public:
    Button(Command& command) : command(command) {}

    void press() {
        command.execute();
    }
};

在客户端代码中,我们可以创建电灯对象、电视对象、命令对象和按钮对象,并将命令对象与接收者对象关联起来,最后按下按钮来执行操作:

int main() {
    Light light;
    TV tv;

    Command* lightOnCommand = new LightOnCommand(light);
    Command* tvOffCommand = new TVOffCommand(tv);

    Button lightButton(*lightOnCommand);
    Button tvButton(*tvOffCommand);

    lightButton.press();  // 按下电灯按钮,执行打开电灯操作
    tvButton.press();     // 按下电视按钮,执行关闭电视操作

    delete lightOnCommand;
    delete tvOffCommand;

    return 0;
}

在上述示例中,我们使用命令模式将具体的操作(打开电灯、关闭电视)封装成命令对象,并将命令对象与接收者对象关联起来。通过创建具体的命令对象并将其传递给按钮对象,可以实现在按下按钮时执行相应的操作。

3 总结

命令模式的优点在于它实现了请求者与执行者之间的解耦,使得请求者不需要知道请求的具体执行者是谁,只需创建和传递相应的命令对象即可执行请求。这样可以支持对请求进行各种操作,比如排队、记录日志和撤销操作。同时,命令模式也符合开闭原则,可以方便地增加新的命令类和接收者类,而无需修改现有的代码。