现在的位置: 首页 > 综合 > 正文

【2013.2.25】我命格无双,一统江山。——Command

2018年02月19日 ⁄ 综合 ⁄ 共 2286字 ⁄ 字号 评论关闭

// // // // // // // // //

///2013.2.25

// // // // // // // // //

花了一个多星期,

终于将三国志ⅢDS通关了。

从孑立之一禺,

索良才,修农商,盟良国,战四方。

以火攻,凭智取,明连锁,暗度仓。

禺鼠至群雄,

群雄至豪杰,

豪杰成霸主,

霸主而坐天下。

然而完成这一切,

笔者也未出茅庐,

——顶多只是上过几次茅庐而已。


科技时代,

真的是让古人无地自容了。

但是备哥哥在不知不觉之间,

却为后人设计程序提供了很好的思想方针。

据史书记载,

刘备总喜欢说这几句话:

"二弟,人手不够了,去征些兵吧"

"三弟,府里米粮不足,去买一些吧"

"诸葛先生,洒家近日略感不适,这些文书还是有劳你了"

"阿云,去帮我借本三国演义来看看吧,我不知道该怎么进行下一步了…"

“超哥,你去……”

所谓的君主范,

就是要做好一天不喝水也下下达三十多条命令的心理准备。

但是不管怎样,

命令还是被执行了,

兵征来了,米粮有了,文书批了,三国演义也借来了,超哥也去了……

命令发布者——刘备

命令——刘备的话

接受者——众人

这,

就是Command模式。

【核心】通过将命令与执行解耦,从而达到间接执行的目的。


UML图:

Command所做的事情,

就是通过Invoker唤醒Command从而使Receiver执行Action.

虽然听起来稍微有点绕,

但无疑这是一个最为标准的面向对象设计思想:

假如二弟不在身边,

刘备依然可以下达命令,

让别人去执行。

这简直就是解耦的模范示例。

示例代码

【大致思路】

Invoker唤醒Command从而使Command作用范围之内(此处即封装)的Receiver执行相应的命令。


Receiver.h

#ifndef _RECEIVER_H_
#define _RECEIVER_H_
#include<iostream>

using namespace std;

class Receiver
{
public:
	Receiver(){}
	~Receiver(){}

	void executeFirstAction()
	{
		cout<<"Guan yu go to buy food."<<endl;
	}

	void executeSecondAction()
	{
		cout<<"Zhang fei go to recruit soldiers."<<endl;
	}
};

#endif

Command.h

#ifndef _COMMAND_H_
#define _COMMAND_H_

class Receiver;

class Command
{
public:
	Command(){}
	~Command(){}

	virtual void Execute() = 0;
};

class ConcreteCommand: public Command
{
public:
	typedef void (Receiver::* Action)();
	ConcreteCommand(Receiver* r,Action a);
	~ConcreteCommand(){}

	void Execute();

private:
	Receiver* rec;
	Action act;
};
	

#endif

Command.cpp

#include"Command.h"
#include"Receiver.h"

ConcreteCommand::ConcreteCommand(Receiver* receiver,Action action)
{
	rec =receiver;
	act = action;
}

void ConcreteCommand::Execute()
{
	(rec->* act)();
}

Invoker.h

#ifndef _INVOKER_H_
#define _INVOKER_H_
#include"Command.h"

class Invoker
{
public:
	Invoker(Command* command)
	{
		com = command;
	}

	~Invoker(){}

	void Invoke()
	{
		com->Execute();
	}

private:
	Command* com;
};

#endif

main.cpp

#include"Invoker.h"
#include"Receiver.h"

int main()
{
	Receiver* receiver = new Receiver();
	
	Command* commandToGuanYu = new ConcreteCommand(receiver,&Receiver::executeFirstAction);
	Command* commandToZhangFei = new ConcreteCommand(receiver,&Receiver::executeSecondAction);

	cout<<"First Command: "<<endl;
	Invoker* invoker = new Invoker(commandToGuanYu);
	invoker->Invoke();

	cout<<endl;
	cout<<"Second Command: "<<endl;
	invoker = new Invoker(commandToZhangFei);
	invoker->Invoke();

	return 0;
}

输出结果:


【注意事项】

其实这里稍微用了一点点技巧,

使用了C++的函数指针。

该怎么解释这个东西呢?

应该说是与C#的委托很相似吧。

总之就是可以代表具有相同签名的函数的一个指针变量。

当然,

设计模式都是这样,

几乎没有一个设计模式是纯粹简单的代码集合,

更多时候是配合一些高级用法来使用的。

希望大家能够渐渐熟悉这些功能,

尽管没有被当做示例代码放在教科书中,

但是却是成熟代码中不可缺少的。

Know it,and get it.

抱歉!评论已关闭.