设计模式---命令模式

104 阅读2分钟

定义

命令模式(Command Pattern)是一种行为设计模式,它将请求或操作封装为一个对象,从而使你可以将请求发送者与请求接收者解耦。这种模式提供了一个对象来表示要执行的命令,并允许你在不暴露请求细节的情况下参数化对象,支持撤销操作以及对命令的排队和日志记录等功能。

结构

  • 命令接口(Command) :声明一个执行操作的接口。

  • 具体命令(ConcreteCommand) :实现 Command 接口,定义与接收者的绑定,并调用接收者的相应操作。

  • 接收者(Receiver) :实际执行命令的对象。知道如何实现与执行相关的操作。

  • 调用者(Invoker) :要求执行一个命令。它保持对命令对象的引用,并在需要时调用命令对象的 execute 方法。

优点

  • 解耦:将请求发起者与请求接收者解耦。调用者只知道命令接口,不需要知道接收者的细节。

  • 灵活性:可以容易地增加新的命令,而不需要改变现有的代码。

  • 撤销操作:可以实现撤销功能,记录执行的命令并允许回滚。

  • 命令参数化:可以将请求参数化为对象,实现排队、日志记录等功能。

代码示例

饭店点菜流程的简单实现,服务员记录顾客点的菜品,并向厨师发送做菜命令。

#include <iostream>
#include <vector>

// 接收者:厨师类
class Cooker
{
public:
	// 麻婆豆腐
	void cookTofu()
	{
		std::cout << "麻婆豆腐出锅" << std::endl;
	}

	// 烤鱼
	void cookFish()
	{
		std::cout << "烤鱼出锅" << std::endl;
	}
};


// 抽象命令类
class Command
{
protected:
	Cooker* receiver;

public:
	Command(Cooker* receiver) : receiver(receiver) {}

	// 执行命令
	virtual void excuteCommand() = 0;
};


// 具体命令1:制作麻婆豆腐
class TofuCommand : public Command
{
public:
	TofuCommand(Cooker* receiver) : Command(receiver) {}

	void excuteCommand() override
	{
		receiver->cookTofu();
	}
};


// 具体命令2:制作烤鱼
class FishCommand : public Command
{
public:
	FishCommand(Cooker* receiver) : Command(receiver) {}

	void excuteCommand() override
	{
		receiver->cookFish();
	}
};


// 调用者:服务员类
class Waiter
{
private:
	std::vector<Command*> orders;

public:
	// 设置订单
	void setOrder(Command* command)
	{
		orders.push_back(command);
	}

	// 通知执行
	void notifyCommand()
	{
		for (const auto& it : orders)
		{
			it->excuteCommand();
		}
	}
};


int main()
{
	Cooker cooker;
	Waiter waiter;

	// 创建具体命令
	Command* cmd1 = new TofuCommand(&cooker);
	Command* cmd2 = new TofuCommand(&cooker);
	Command* cmd3 = new TofuCommand(&cooker);
	Command* cmd4 = new FishCommand(&cooker);
	Command* cmd5 = new FishCommand(&cooker);

	//设置订单
	waiter.setOrder(cmd1);
	waiter.setOrder(cmd2);
	waiter.setOrder(cmd3);
	waiter.setOrder(cmd4);
	waiter.setOrder(cmd5);
	
	// 执行命令
	waiter.notifyCommand();

	system("pause");
	return 0;
}
```cpp