本文介绍: 可以看到我们设置命令打开电灯按下按钮电灯已经打开执行撤销方法电灯就被关闭然后我们设置命令关闭电灯执行撤销方法,电灯就被打开。4、接口隔离原则命令模式通过抽象命令和具体命令设计可以不同请求封装不同命令类,从而避免大量的接口同一个类中定义。1、抽象命令:它定义执行操作的接口,包含一个执行方法和一个可选的撤销操作这里撤销撤销命令,恢复成上一个命令执行结果。3、里氏替换原则:命令模式中的具体命令类是抽象命令的子类,因此可以通过具体命令类的替换扩展和改变命令的行为

命令模式是一种行为设计模式,它将请求封装一个对象,从而能使你可以不同请求客户端进行参数化。该模式允许请求的发送者接收者进行解耦,发送者需要知道接收者信息,只需要通过命令对象来与它进行交互

命令模式有四个角色

1、抽象命令:它定义了执行操作的接口,包含一个执行方法和一个可选的撤销操作这里撤销撤销命令,恢复成上一个命令执行结果

2、具体命令:实现了命令接口,持有接收者对象引用负责接收者执行操作

3、接收者执行命令代表操作

4、调用者:持有命令对象发送请求并触发命令执行。

举例:

使用遥控器控制电灯的开和关。

#include <iostream>
#include <memory&gt;

// 接收者-电灯
class Light
{
public:

	void On()
	{
		std::cout << "电灯已经打开" << std::endl;
	}

	void Off()
	{
		std::cout << "电灯已经关闭" << std::endl;
	}
};

// 抽象命令
class ICommand
{
public:

	virtual ~ICommand() {}

	virtual void Execute() = 0;

	virtual void Undo() = 0;

protected:

	std::shared_ptr<Light&gt; light_;
};

// 具体命令-打开电灯
class CloseLight
	: public ICommand
{
public:

	CloseLight(std::shared_ptr<Light> _light)
	{
		light_ = _light;
	}

	virtual void Execute() override
	{
		light_->On();
	}

	virtual void Undo() override
	{
		light_->Off();
	}
};

// 具体命令-关闭电灯
class OpenLight
	: public ICommand
{
public:

	OpenLight(std::shared_ptr<Light> _light)
	{
		light_ = _light;
	}

	virtual void Execute() override
	{
		light_->Off();
	}

	virtual void Undo() override
	{
		light_->On();
	}
};

// 调用者-遥控器
class RemoteControl
{
public:

	void SetCommand(std::shared_ptr<ICommand> _command)
	{
		command_ = _command;
	}

	void PressButton()
	{
		if(command_)
			command_->Execute();
	}

	void Undo()
	{
		if(command_)
			command_->Undo();
	}

private:

	std::shared_ptr<ICommand> command_;
};

示例中,我们首先定义了一个抽象命令接口(ICommand),定义了两个方法Exectue()和Undo(),分别用于执行操作和撤销命令。

然后我们又创建两个具体的命令类(OpenLight)和(CloseLight),分别实现了这两个方法。这些具体命令类会持有对接收者对象(Light)的引用,通过执行方法调用相应的操作

最后创建一个调用者角色(RemoteControl)作为遥控器。遥控器持有一个命令对象,提供设置命令对象触发命令的执行方法。通过按下(PressButton)执行具体的命令,通过Undo撤销命令。

测试

void TestCommand()
{
	// 创建接收者
	std::shared_ptr<Light> light = std::make_shared<Light>();

	// 创建命令
	std::shared_ptr<ICommand> openLight = std::make_shared<OpenLight>(light);
	std::shared_ptr<ICommand> closeLight = std::make_shared<CloseLight>(light);

	// 创建调用者
	std::shared_ptr<RemoteControl> remoteControl = std::make_shared<RemoteControl>();

	// 设置命令
	remoteControl->SetCommand(openLight);
	remoteControl->PressButton();
	remoteControl->Undo();

	remoteControl->SetCommand(closeLight);
	remoteControl->Undo();
}

测试代码中,我们创建了两个具体命令:打开电灯和关闭电灯、一个接收者,也就是电灯、一个遥控器对象

通过遥控器设置命令,按下按钮,就可以执行具体的命令。

输出结果:

电灯已经打开
电灯已经关闭
电灯已经打开

可以看到,我们先设置命令为打开电灯,按下按钮,电灯已经打开,执行撤销方法,电灯就被关闭然后我们设置命令为关闭电灯,执行撤销方法,电灯就被打开。

所以这里的撤销其实是撤销当前命令

命令模式遵顼的设计原则:

1、单一职责原则:每个命令类负责执行一个特定的命令。

2、开放封闭原则:可以动态添加删除命令,不影响现有代码

3、里氏替换原则:命令模式中的具体命令类是抽象命令的子类,因此可以通过具体命令类的替换扩展和改变命令的行为。

4、接口隔离原则:命令模式通过抽象命令和具体命令的设计,可以将不同的请求封装不同的命令类,从而避免大量的接口在同一个类中定义。

优点:

1、解耦对象间的关系:命令模式将请求者和接收者解耦,使得命令发送者需要知道抽象命令类,不需要知道具体的接收者,降低了系统耦合度。

2、容易扩展新的命令:新增一个命令非常容易,不需要修改现有代码,符合开闭原则。

3、支持撤销和重做操作:命令模式可以将命令对象存储历史记录中,实现命令的撤销和重做

4、支持队列请求和日志化请求:命令模式可以将命令对象放入队列中,实现对请求的排队和延迟执行,还可以将命令对象做持久处理实现对请求的日志记录

缺点:

1、增加了系统复杂度引入多个命令类、接收者类、调用类,增加了系统复杂度

2、可能会使类膨胀每个命令都需要一个具体的命令类去实现,如果命令太多,就会造成类的数量过于膨胀,增加了系统的维护成本

原文地址:https://blog.csdn.net/m0_51415606/article/details/134770674

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_35310.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注