命令模式一般叫:command模式,它将请求的发送者和接受者独立开。命令模式的目的是使得请求的发送者与请求的接收者解耦,并且使得请求的发送者可以控制请求的接收者。
目录
一、命令模式能干什么?
二、多级命令
三、进阶写法
一、命令模式能干什么?
好多时候我们并不明确眼前熟悉事物的重要性以及它呈现在你面前的难能可贵,好像世间本就存在C语言,有C语言就一定有C plus plus,其实不然,这也是我们为什么要知道历史,屈辱的历史可以带来反省,骄傲的历史可以带来自信。
对于命令模式来讲,刚了解时我并不觉得有什么特殊的地方,只是看到了命令被封装在发送者和接受者之间转换。那么我们就举一个反例,来看看改进成命令模式后有什么进步。
我们先给出一个简单的智能家居控制代码:
class Light {
public:
void turnOn() {
cout << "Light is on." << endl;
}
void turnOff() {
cout << "Light is off." << endl;
}
};
class AirConditioner {
public:
void turnOn() {
cout << "Air conditioner is on." << endl;
}
void turnOff() {
cout << "Air conditioner is off." << endl;
}
};
class RemoteControl {
public:
void turnOnLight() {
light_.turnOn();
}
void turnOffLight() {
light_.turnOff();
}
void turnOnAirConditioner() {
air_conditioner_.turnOn();
}
void turnOffAirConditioner() {
air_conditioner_.turnOff();
}
private:
Light light_;
AirConditioner air_conditioner_;
};
int main() {
RemoteControl remote_control;
remote_control.turnOnLight();
remote_control.turnOffLight();
remote_control.turnOnAirConditioner();
remote_control.turnOffAirConditioner();
return 0;
}
这段代码将遥控器和被控制的对象(灯和空调)耦合在一起,导致代码难以维护和扩展。如果想要添加新的设备,就需要在遥控器类中添加新的方法,这样的代码显得非常冗长和不灵活。
类图:
下面来一段使用命令模式的代码:
class Command {
public:
virtual ~Command() = default;
virtual void execute() = 0;
};
class Light {
public:
void turnOn() {
cout << "Light is on." << endl;
}
void turnOff() {
cout << "Light is off." << endl;
}
};
class AirConditioner {
public:
void turnOn() {
cout << "Air conditioner is on." << endl;
}
void turnOff() {
cout << "Air conditioner is off." << endl;
}
};
class LightOnCommand : public Command {
public:
explicit LightOnCommand(Light* light) : light_(light) {}
void execute() override {
light_->turnOn();
}
private:
Light* light_;
};
class LightOffCommand : public Command {
public:
explicit LightOffCommand(Light* light) : light_(light) {}
void execute() override {
light_->turnOff();
}
private:
Light* light_;
};
class AirConditionerOnCommand : public Command {
public:
explicit AirConditionerOnCommand(AirConditioner* air_conditioner)
: air_conditioner_(air_conditioner) {}
void execute() override {
air_conditioner_->turnOn();
}
private:
AirConditioner* air_conditioner_;
};
class AirConditionerOffCommand : public Command {
public:
explicit AirConditionerOffCommand(AirConditioner* air_conditioner)
: air_conditioner_(air_conditioner) {}
void execute() override {
air_conditioner_->turnOff();
}
private:
AirConditioner* air_conditioner_;
};
class RemoteControl {
public:
void setCommand(int slot, Command* on_command, Command* off_command) {
on_commands_[slot] = on_command;
off_commands_[slot] = off_command;
}
void onButtonWasPressed(int slot) {
on_commands_[slot]->execute();
}
void offButtonWasPressed(int slot) {
off_commands_[slot]->execute();
}
private:
vector<Command*> on_commands_;
vector<Command*> off_commands_;
};
int main() {
RemoteControl remote_control;
Light light;
AirConditioner air_conditioner;
LightOnCommand light_on_command(&light);
LightOffCommand light_off_command(&light);
AirConditionerOnCommand air_conditioner_on_command(&air_conditioner);
AirConditionerOffCommand air_conditioner_off_command(&air_conditioner);
remote_control.setCommand(0, &light_on_command, &light_off_command);
remote_control.setCommand(1, &air_conditioner_on_command,
&air__off_command)
remote_control.onButtonWasPressed(0);
remote_control.offButtonWasPressed(0);
remote_control.onButtonWasPressed(1);
remote_control.offButtonWasPressed(1);
return 0;
}
通过使用命令模式,你可以在不改变已有代码的前提下,向系统中加入新的命令。增强了代码的可维护性、可读性等。
类图:
二、多级命令
实现多级命令的方法是在命令类中再次使用命令模式,每一个命令都是另一个命令的容器。
#include <vector>
#include <iostream>
class Command {
public:
virtual void Execute() = 0;
};
class Light {
public:
void On() {
std::cout << "Light is on" << std::endl;
}
void Off() {
std::cout << "Light is off" << std::endl;
}
};
class LightOnCommand : public Command {
public:
LightOnCommand(Light& light) : light_(light) {}
void Execute() override {
light_.On();
}
private:
Light& light_;
};
class LightOffCommand : public Command {
public:
LightOffCommand(Light& light) : light_(light) {}
void Execute() override {
light_.Off();
}
private:
Light& light_;
};
class MacroCommand : public Command {
public:
MacroCommand(std::vector<Command*> commands) : commands_(commands) {}
void Execute() override {
for (auto& command : commands_) {
command->Execute();
}
}
private:
std::vector<Command*> commands_;
};
int main() {
Light light;
LightOnCommand light_on_command(light);
LightOffCommand light_off_command(light);
std::vector<Command*> macro_commands;
macro_commands.push_back(&light_on_command);
macro_commands.push_back(&light_off_command);
MacroCommand macro_command(macro_commands);
macro_command.Execute();
return 0;
}
上面的代码实现了一个简单的多级命令示例,它定义了一个MacroCommand
类,用于执行一组命令。
类图:
三、进阶写法
进阶命令模式包含多级命令、命令队列、命令历史、撤销和重做。
#include <iostream>
#include <vector>
#include <stack>
// 命令基类
class Command {
public:
virtual void Execute() = 0;
virtual void UnExecute() = 0;
};
// 具体命令类
class ConcreteCommand : public Command {
public:
ConcreteCommand(int value) : value_(value) {}
void Execute() override {
std::cout << "Executing Command with value: " << value_ << std::endl;
}
void UnExecute() override {
std::cout << "Unexecuting Command with value: " << value_ << std::endl;
}
private:
int value_;
};
// 多级命令
class CompositeCommand : public Command {
public:
void AddCommand(Command* command) {
commands_.push_back(command);
}
void Execute() override {
for (auto command : commands_) {
command->Execute();
}
}
void UnExecute() override {
for (auto command : commands_) {
command->UnExecute();
}
}
private:
std::vector<Command*> commands_;
};
// 命令队列
class CommandQueue {
public:
void AddCommand(Command* command) {
commands_.push_back(command);
}
void ExecuteCommands() {
for (auto command : commands_) {
command->Execute();
}
}
void UnExecuteCommands() {
for (auto command : commands_) {
command->UnExecute();
}
}
private:
std::vector<Command*> commands_;
};
// 命令历史
class CommandHistory {
public:
void PushCommand(Command* command) {
commands_.push(command);
}
Command* PopCommand() {
if (commands_.empty()) {
return nullptr;
}
auto command = commands_.top();
commands_.pop();
return command;
}
private:
std::stack<Command*> commands_;
};
int main() {
// 创建命令
auto command1 = new ConcreteCommand(1);
auto command2 = new ConcreteCommand(2);
auto command3 = new ConcreteCommand(3);
// 创建多级命令
auto composite_command = new CompositeCommand();
composite_command->AddCommand(command1);
composite_command->AddCommand(command2);
// 创建命令队列
auto command_queue = new CommandQueue();
command_queue->AddCommand(command1);
command_queue->AddCommand(command2);
command_queue->AddCommand(command3);
// 创建命令历史
auto command_history = new CommandHistory();
command_history->PushCommand(command1);
command_history->PushCommand(command2);
command_history->PushCommand(command3);
// 执行多级命令
composite_command->Execute();
// 执行命令队列
command_queue->ExecuteCommands();
// 撤销命令
auto command = command_history->PopCommand();
if (command) {
command->UnExecute();
}
return 0;
}
类图: