命令模式

命令模式

1.何为命令模式

​ 将一个请求封装为一个对象,向对象发送命令来指导它们做事,从而可用不同的请求来指导对象不同的行为。如此可以实现请求排队、记录请求日志、撤销请求、事务等操作。实现“行为”和“组件”的解耦。

2.命令模式的意义和使用场景

​ 在软件构建过程中,行为请求者和行为实现者通常是紧耦合关系,但在某些场合需要对请求进行记录、撤销、事务等操作,这种耦合是不合适的。所以将操作指令封装为一个命令对象,用于对象之间的通信,比通过函数参数通信更方便、灵活。

3.命令模式的实现

​ 设计一个命令抽象基类,然后通过继承实现各种命令。也可以实现复合命令,即命令对象中用一个数组存放命令集。还可以将 查询命令和请求命令分开,就像sql一样。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
// 命令基类
class Command {
public:
virtual void execute() = 0;//执行
virtual void undo() = 0;//撤销
};

// 命令接收者
class Light {
public:
void turnOn() {
std::cout << "Light is ON" << std::endl;
}

void turnOff() {
std::cout << "Light is OFF" << std::endl;
}
};
// 具体命令
class TurnOnLightCommand : public Command {
private:
Light& light;
string args;//命令参数
public:
TurnOnLightCommand(Light& l,arg) : light(l),args(arg) {}
void execute() override {
light.turnOn();
}
void undo() override {
light.turnOff();
}
};
// 具体命令
class TurnOffLightCommand : public Command {
private:
Light& light;
string args;//命令参数
public:
TurnOffLightCommand(Light& l) : light(l),args(arg) {}

void execute() override {
light.turnOff();
}
void undo() override {
light.turnOn();
}
};
//复合命令
class LightCommands : public Command {
private:
vector<Command*> commands;
public:
TurnOffLightCommand() {}
void addcommand(Command* cmd)
void execute() override {
for(auto i : commands)
{
i->execute();
}
}
};


需要指出的是,在c++中由于性能的需求,实际应用中,许多命令模式被范式编程+仿函数代替。命令模式用接口-实现来定义行为接口规范,更严格,但性能有所损失。函数对象(仿函数)以函数签名定义行为规范,更灵活,性能高。