命令模式是一种行为行模式,适用于专用场合,代码有些繁琐。

通过一个范例引出命令模式代码编写方法

下面的场景,假如有一个饭店,顾客给服务员点菜,然后服务员把客人点好的菜单给了厨师,这种场景下就适合命令模式。

	// 厨师类
	class Cook
	{
	public:
		void cook_fish()
		{
			cout << "厨师 做了 红烧鱼" << endl;
		}
		void cook_meat()
		{
			cout << "厨师 做一盘锅包肉" << endl;
		}
	};

	class Command
	{
	public:
		Command(Cook* pcook) { m_pcook = pcook; }
		virtual ~Command()
		{
			if (m_pcook != nullptr)
			{
				delete m_pcook;
				m_pcook = nullptr;
			}
		}
		virtual void Execute() = 0;

	protected:	// 在子类中访问
		Cook* m_pcook;
	};

	class CommandFish : public Command
	{
	public:
		CommandFish(Cook* pc) : Command(pc) {}

		virtual void Execute() override
		{
			m_pcook->cook_fish();
		}
	};

	class CommandMeat : public Command
	{
	public:
		CommandMeat(Cook* pc) : Command(pc) {}

		virtual void Execute() override
		{
			m_pcook->cook_meat();
		}
	};

	// 服务员类
	class Waiter
	{
	public:
		void AddCommand(Command* pcmd)
		{
			m_listCommand.push_back(pcmd);
		}
		void DelCommand(Command* pcmd)
		{
			m_listCommand.remove(pcmd);
		}

		void Notify() // 服务员 将所有的便签加入到厨师的队列中
		{
			for (Command* pcmd : m_listCommand)
			{
				pcmd->Execute();
			}
		}
	private:
		list<Command*> m_listCommand;  // 存放多个菜品;
	};

	// 一次性传递多个菜品,当前代码就是命令模式
	void test3()
	{
		Cook* pcook = new Cook();
		CommandFish* pcmdfish = new CommandFish(pcook);
		CommandMeat* pcmdmeat = new CommandMeat(pcook);
		Waiter* pw = new Waiter(); // 服务员 
		pw->AddCommand(pcmdfish); // 服务员类将菜 加入到菜单中
		pw->AddCommand(pcmdmeat);
		pw->Notify();	// 通知厨师做菜
	}

命令(Command)模式定义和UML

在这里插入图片描述
UML的五种角色,
1 Receive 接受者类:知道如何实施与执行官一个请求相关的操作,这里指Cook相关的类,提供了对请求的业务进行处理的接口。
2 Invoke调用者类。请求的发送者,通过命令对象来执行请求,这里指Waiter类,该类只与抽象命令类Command之间存在关联关系。
3 Command类,声明执行操作的接口。这里指的是Command类,在其中声明了用于执行请求的Execute方法,用于接受者的相关操作。
4 ConcreteCommand类,抽象命令的子类,这里指CommandFish类和CommandMeat类,类中实现了执行请求的Execute方法来调用Cook中的相关操作。
5 Client类,创建具体的命令类对象并设置它的接受者,这里指main主函数中的代码。
命令模式的定义:将一个请求或者命令封装为一个对象,以便这些请求可以以对象的方式通过参数传递,对象化了的请求还可以排队执行或者根据需要将这些请求录入日志共查看和排错,以及支持请求执行后的可撤销操作。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐