C++设计模式-命令模式详解

命令模式:讲每个命令封装成一个个对象,让不同的接受者参数化命令,接受者可以执行或者撤销命名。

公司最近新接了一个项目,老板很是高兴,命令公司全力配合完成好这个项目。为此我把公司分成了两个项目小组,一个是代码实现组,一个是界面美工组。
这两个小组通力合作来完成好。

刚开始的时候客户的需求是明确的,也给列出来的明确的需求列表,界面的布局和颜色搭配客户也给出了一个大概的要求。然后大家很快地就完成了第一版,拿给客户看的时候,客户觉得有部分功能不是他想要的样子,然后把代码组的叫过去,把自己的详细的功能要求给代码组说了一下,代码组明白之后马上回去讨论修改;客户又觉得这个界面的颜色的配置不是很好看,又把美工组叫过去谈了一下界面配色的看法,既然是客户提出的要求,美工组当然全力配合了。

很快大家有完成了一版,客户看完之后,对之前提出的修改又反悔了,还是觉得原来的实用好看,又让大家修改回去。没办法客户就是上帝。回头代码组和美工组就有很快的把程序恢复到原来的样子。

又给客户看的时候,客户又提出了其他的要求,分别又把代码组和美工组交过去做了相应的调整,代码组和项目组又回去根据客户的需求修改了相应的部分功能和界面,修改完成之后拿给客户看看,如此反复。。。

最后客户提出不要每次都把两个项目组的都叫过来,人一多大家七嘴八舌,很乱,只要把项目经理叫过来,客户把需要修改的功能和调整的界面给项目经理说一下就可以了,然后让项目经理分别给两个组分配工作,这样多好。如果客户那边派了另外一个人过来,或者代码组成员发生了变化,都不会影响项目的进度。客户只要提出一个需求,两个组分别根据客户的需求做出相应的调整就可以了。

好,上面的场景已经说完了,下面咱们看看如何通过代码来实现吧。

两个项目每次接到新的需求变化,都会有谈论、修改、完成这几步。所以把共同的部分提出来,行程一个基类。

//项目组基类
class IGroup {
public:
	IGroup();
	~IGroup();

	//开会讨论
	virtual void talk();
	//行动
	virtual void action();

	//完成
	virtual void finish();
};

//项目组基类
class IGroup {
public:
	IGroup();
	~IGroup();

	//开会讨论
	virtual void talk();
	//行动
	virtual void action();

	//完成
	virtual void finish();

	//回滚撤销
	virtual void rollBack();
};

代码组:

//代码组
class CodeGroup : public IGroup {
public:
	void talk()override;
	void action()override;
	void finish()override;
private:
	std::string _code = "hello!";
	std::string _oldCode;
};

void CodeGroup::talk() {
	printf("开始讨论如何修改代码!\n");
}

void CodeGroup::action() {
	_oldCode = _code;
	_code = "hello world!";
	printf("开始修改代码,以实现客户的需求!\n");
}

void CodeGroup::finish() {
	printf("完成修改,给客户展示结果!  %s\n", _code.c_str());
}

美工组

//美工组
class DrawGroup :public IGroup {
public:
	void talk()override;
	void action()override;
	void finish()override;

private:
	std::string _color = "red";
	std::string _oldColor;
};

void DrawGroup::talk() {
	printf("开始讨论如何配置界面颜色!\n");
}

void DrawGroup::action() {
	_oldColor = _color;
	_color = "blue";
	printf("开始修改界面颜色,以满足客户的需求!\n");
}

void DrawGroup::finish() {
	printf("完成修改,给客户展示界面效果! 界面颜色现在是%s\n", _oldColor.c_str());
}

客户每次提出需求就相当于每次发布一个命令,项目组成员就要根据客户提出的需求来完成相应的功能调整。

先抽象出命令基类:

//命令接口基类
class ICommand {
public:
	ICommand();
	~ICommand();

	virtual void execute();
protected:
	CodeGroup* _codeGroup = nullptr;
	DrawGroup* _drawGroup = nullptr;
};

ICommand::ICommand() {
	_codeGroup = new CodeGroup;
	_drawGroup = new DrawGroup;
}

ICommand::~ICommand() {
}

void ICommand::execute() {

}

客户会有不同的需求,也就是会有不同命令;

//修改代码命令
class ModifyCodeCommand :public ICommand {
public:
	void execute()override;
};

//修改界面命令
class ModifyDrawCommand :public ICommand {
public:
	void execute()override;
};


void ModifyCodeCommand::execute() {
	_codeGroup->talk();
	_codeGroup->action();
	_codeGroup->finish();
}

void ModifyDrawCommand::execute() {
	_drawGroup->talk();
	_drawGroup->action();
	_drawGroup->finish();
}


好了,需要的已经完成,看看客户端的调用结果:

int main() {
	ICommand* modifyCode = new ModifyCodeCommand;
	modifyCode->execute();
	
	ICommand* modifyDraw = new ModifyDrawCommand;
	modifyDraw->execute();

	return 0;
}

运行结果:
在这里插入图片描述

好的已经完成了。

可能你觉得把项目组封装到外面比较好,这个可以独立的关注他们的变化,不至于项目组和命令有太多的耦合。
那好,我们就修改一下代码:

//命令接口基类
class ICommand {
public:
	ICommand();
	~ICommand();

	virtual void execute();
};

//修改代码命令
class ModifyCodeCommand :public ICommand {
public:
	ModifyCodeCommand(IGroup* group);
	void execute()override;
private:
	IGroup* _group;
};

class ModifyDrawCommand :public ICommand {
public:
	ModifyDrawCommand(IGroup* group);
	void execute()override;
private:
	IGroup* _group;
};
 王彪台式电脑 11:07:14
ICommand::ICommand() {
	
}

ICommand::~ICommand() {
}

void ICommand::execute() {

}

ModifyCodeCommand::ModifyCodeCommand(IGroup* group) {
	_group = group;
}

void ModifyCodeCommand::execute() {
	_group->talk();
	_group->action();
	_group->finish();
}

ModifyDrawCommand::ModifyDrawCommand(IGroup* group) {
	_group = group;
}

void ModifyDrawCommand::execute() {
	_group->talk();
	_group->action();
	_group->finish();
}

然后看看客户端调用:

int main() {

	IGroup* codeGroup = new CodeGroup;

	ICommand* modifyCode = new ModifyCodeCommand(codeGroup);
	modifyCode->execute();


	IGroup* drawGroup = new DrawGroup;
	ICommand* modifyDraw = new ModifyDrawCommand(drawGroup);
	modifyDraw->execute();


	return 0;
}

发布命令后想让谁去执行就可以给命令传递相应的项目组就可以了。是不是很棒!

运行结果:
在这里插入图片描述

结果是一样的!

命令模式的优点:

1.解耦合命令的发布者和执行者,发布者只需要发布命令就可以,无需知道执行者是谁,发布者和执行者可以独立的进行修改;

2.可以扩展不同的命令,以适应项目的需求变化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wb175208

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值