设计模式之命令设计模式

一、命令设计模式概念

命令模式(Command) 是一种行为设计模式, 它可将请求转换为一个包含与请求相关的所有信息的独立对象。 该转换让你能根据不同的请求将方法参数化、 延迟请求执行或将其放入队列中, 且能实现可撤销操作。

 适用场景

  • 如果你需要通过操作来参数化对象, 可使用命令模式。
  • 如果你想要将操作放入队列中、 操作的执行或者远程执行操作, 可使用命令模式。
  • 如果你想要实现操作回滚功能, 可使用命令模式。

命令设计模式的结构

  1. 发送者 (Sender)——亦称 “触发者 (Invoker)”——类负责对请求进行初始化, 其中必须包含一个成员变量来存储对于命令对象的引用。 发送者触发命令, 而不向接收者直接发送请求。 注意, 发送者并不负责创建命令对象: 它通常会通过构造函数从客户端处获得预先生成的命令。

  2. 命令 (Command) 接口通常仅声明一个执行命令的方法。

  3. 具体命令 (Concrete Commands) 会实现各种类型的请求。 具体命令自身并不完成工作, 而是会将调用委派给一个业务逻辑对象。 但为了简化代码, 这些类可以进行合并。

    接收对象执行方法所需的参数可以声明为具体命令的成员变量。 你可以将命令对象设为不可变, 仅允许通过构造函数对这些成员变量进行初始化。

  4. 接收者 (Receiver) 类包含部分业务逻辑。 几乎任何对象都可以作为接收者。 绝大部分命令只处理如何将请求传递到接收者的细节, 接收者自己会完成实际的工作。

  5. 客户端 (Client) 会创建并配置具体命令对象。 客户端必须将包括接收者实体在内的所有请求参数传递给命令的构造函数。 此后, 生成的命令就可以与一个或多个发送者相关联了。

代码如下:

            问题:模拟小餐馆点餐,客户提交订单给服务员,服务员将订单交给厨师,厨师根据订单做菜,最后将菜端给客户。
            解决方案:将一个请求封装为一个对象,从而使用户可以用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。

#include <iostream>
#include <string>
#include <vector>
class Kitchen {
private:
	Kitchen() {}
public:
	static Kitchen* getInstance()
	{
        static Kitchen* instance=new Kitchen();
		return instance;
	}
	void prepareFood(const std::string& food)
	{
		std::cout << "厨房:正在准备(" << food << ".)\n";
	}
};

//
class Command {
public:
	virtual ~Command() {}
	virtual void excute()const = 0;


};
//ConcreteCommand
class Order :public Command {
private:
    Kitchen* m_kitchen;
	std::vector<std::string> m_foods;
public:
	Order(Kitchen* kitchen, const std::vector<std::string> foods)
        :m_kitchen(kitchen), m_foods(foods)
	{

	}
	virtual ~Order() {}
	virtual void excute()const override
	{
		std::cout << "订单:将订单送往厨房...\n";
		for (const auto& food : m_foods)
		{
			m_kitchen->prepareFood(food);
		}
	}
};

//Invoker
class Waiter {
private:
	Command* m_command;
public:
	~Waiter() { delete m_command; }
	void orderUp(Command* command)
	{
		std::cout << "服务员:订单已提交...\n";
        m_command = command;//用于回收内存
		m_command->excute();
	}

};

//Client
class Client {
public:
	void orderFood(Waiter& waiter, std::vector<std::string> foods)
	{
		waiter.orderUp(new Order(Kitchen::getInstance(), foods));

	}
};
int main()
{
	Client client;
	Waiter waiter;
	client.orderFood(waiter,{"鱼香肉丝", "宫保鸡丁", "红烧肉"});
	return 0;
}

 二、与其他模式的关系

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值