C++ 命令模式

什么是命令模式?

  • 将请求转换为一个包含与请求相关的所有信息的独立对象。从而使你可以用不同的请求方法进行参数化,并且能够对请求进行排队、记录请求日志以及撤销请求操作。
  • 命令模式属于行为设计模式
如何理解命令模式

命令模式很像我们订外卖(淘宝),用户下单,订单中包裹了商户的信息及订餐数量,外卖平台作为接收者将订单再通知到商户,商户执行操作。

命令模式的步骤

源自ChatGpt的总结

  1. 定义一个 Command 抽象类,它声明了一个抽象的 execute() 方法,该方法用于执行命令。
  2. 创建一个实现了 Command 抽象类的实体类,该类实现了 execute() 方法,用于执行具体的命令。
  3. 创建一个 Invoker 类,该类持有 Command 类的一个实例,并调用实例的 execute() 方法来实现命令的调用。
  4. 创建客户端,在客户端中创建一个具体的 Command 对象,并设置它的接收者。
  5. 创建 Invoker 对象,并将创建的 Command 对象设置到 Invoker 对象中。
  6. 调用 Invoker 对象的 execute() 方法来执行命令。
代码描述

我们这里用户头像为例子

  • 首先需要接口类
/*通用命令*/
class Command {
public:
	virtual ~Command() {}
	virtual void Execute() const = 0;
};
/*通用处理人*/
class Receiver {
public:
	virtual void DoFuncA(const int a)     = 0;
	virtual void DoFuncB(const int b) = 0;
};
  • 创建具体命令
/*实例化一个厨师类的处理人*/
class CookReceiver : public Receiver {
public:
	explicit CookReceiver(const std::string& cook_name) : cook_name_(cook_name) {}
	void DoFuncA(const int a) { 
		std::cout << "->cook " << cook_name_ << " Receiver: Working sum= " << a << std::endl; 
	}
	void DoFuncB(const int b){
		std::cout << "->cook " << cook_name_ << "  Receiver: Working food weight=" << b << std::endl;
	}

private:
	std::string cook_name_;
};
/*实例化一条简单命令*/
class MilkCommand : public Command {
private:
	int sum_;

public:
	explicit MilkCommand(int sum) : sum_(sum) {}
	void Execute() const override { std::cout << "->The customer need milk= " << this->sum_ << std::endl; }
};
/*实例化一条复杂的命令*/
class SteakCommand : public Command {

public:
	explicit SteakCommand(std::shared_ptr<Receiver> receiver_cook, int sum, int weight)
		: sum_(sum), weight_(weight), receiver_cook_(receiver_cook)
	{
	}
	void Execute() const override
	{
		std::cout << "->The customer ordered a steak" << std::endl;
		this->receiver_cook_->DoFuncA(this->sum_);
		this->receiver_cook_->DoFuncB(this->weight_);
	}

private:
	std::shared_ptr<Receiver> receiver_cook_;
	int                       sum_    = 0;
	int                       weight_ = 0;
};
  • 通过中心来分配执行命令
/*饭店前台*/
class Invoker {
private:
	vector<std::shared_ptr<Command>> command_list_;

public:
	~Invoker() { command_list_.clear(); }
	void InsertFontCommand(std::shared_ptr<Command> command) { command_list_.insert(command_list_.begin(), command); }
	void PushBackCommand(std::shared_ptr<Command> command) { command_list_.push_back(command); }
	void ExecuteCommand()
	{
		std::cout << "The customer order start execute!" << std::endl;
		for (auto& item_command : command_list_) {
			item_command->Execute();
		}
		std::cout << "The customer order finished!" << std::endl;
	}
};
  • 创建用户命令并执行
int main()
{
	//饭店前台
	auto invoker            = std::make_shared<Invoker>();
	//创建厨师小明
	auto receiver_cook_user = std::make_shared<CookReceiver>("xiao ming");
	//订购牛排并指定小明厨师制作
	invoker->PushBackCommand(make_shared<SteakCommand>(receiver_cook_user, 5, 100));
	//订购牛奶
	invoker->InsertFontCommand(make_shared<MilkCommand>(5));
	//执行订单
	invoker->ExecuteCommand();
	return 0;
}

  • 输出结果如下
    在这里插入图片描述
命令模式的思考

优点:

  • 单一职责,实现了触发和执行的解耦操作;
  • 复合开闭原则,无需修改原有代码,就可增加新的命令
  • 可以把多个操作组合成一个复杂的命令,从而实现复杂的逻辑
  • 排队中的操作命令可以排序或撤销
  • 维护日志方便,更好的回溯操作

缺点:

  • 简单的逻辑套用命令模式,由于中间传递调用者的加入会变得复杂
  • 如果命令过多,很容易出现类数量膨胀的情况

总结:

  • 如果遇到复杂的问题,尤其是客户端这种,命令模式是一种很好的解耦UI和逻辑的设计方式
命令模式与其他模式的比较
  • 命令在发送者和请求者之间建立单向连接
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值