命令模式不通过调用类的API处理对象,而是通过发送命令…,
实现代码
#include<vector>
#include<string>
#include<map>
#include<iostream>
using namespace std;
struct BankAccount { //银行账户交易逻辑
int balance = 0;
int overdraft_limit = -500;
void deposit(int amount) {
balance += amount;
}
void withdraw(int amount) {
if (balance - amount >= overdraft_limit) {
balance -= amount;
}
}
};
struct Command { //命令的虚基类
virtual void call() = 0;
virtual void undo() = 0;
};
struct BankAccountCommand :Command { //调用命令、撤回命令
BankAccount& account;
enum Action {deposit,withdraw} action;
int amount;
BankAccountCommand(BankAccount& account, const Action action, const int amount) :amount{ amount }, action{ action }, account{account}{}
void call() override {
switch (action) {
case deposit:
account.deposit(amount);
break;
case withdraw:
account.withdraw(amount);
break;
}
}
void undo() override {
switch (action) {
case deposit:
account.withdraw(amount);
break;
case withdraw:
account.deposit(amount);
break;
}
}
};
//既是命令的集合、也是一个命令
struct CompositeBankAccountCommand :vector<BankAccountCommand>, Command {
CompositeBankAccountCommand(const initializer_list<value_type>& items) :vector<BankAccountCommand>(items) {}
void call()override {
for (auto& cmd : *this) //this表示指向向量的指针
cmd.call();
}
void undo()override {
for (auto it = rbegin(); it != rend(); it++) { //继承自vector<>,所以包含这些函数
it->undo();
}
}
};
struct MoenTransferCommand :CompositeBankAccountCommand { //例子:两用户间交互
MoenTransferCommand(BankAccount& from, BankAccount& to, int amount) :CompositeBankAccountCommand{
BankAccountCommand{from,BankAccountCommand::withdraw,amount},
BankAccountCommand{to,BankAccountCommand::deposit,amount}
} {}
};
int main()
{
BankAccount a, b;
MoenTransferCommand temp{ a, b, 300 }; //加载命令
temp.call(); //执行命令
cout << a.balance << " 、 " << b.balance << endl;
temp.undo(); //执行命令
cout << a.balance << " 、 " << b.balance << endl;
/*
-300 、 300
0 、 0
*/
return 0;
}
该例子实现了银行用户交易的命令,由于分为了设置命令、执行命令两步,所以可以实现执行、撤回两种形式。
命令模式
命令模式将操作指令封装成了特殊对象,可以用于对象通讯,并且能够添加更多有关于控制细节方面的信息,用来实现更复杂的控制操作。
除此之外,命令模式还能将命令、执行分离。