首页 > 代码库 > 【设计模式】命令模式

【设计模式】命令模式

命令模式:将请求封装在对象中,客户不直接调用某个对象的方法,而是使用命令,将命令传递给拥有方法的对象从而让某一方法被调用。UML图如下:



下面是用C++描写的命令模式的一个简单例子:

#include <iostream>
#include <string>
#include <list>

using namespace std;

// Interface
class Command {
public:
	virtual void Execute() = 0;
};

/* Invoker命令发送者 */
class Switch {
public:
	// 存储命令
	void Add(Command *command)
	{
		commands.push_back(command);
	}

	// 删除命令
	void Remove(Command *command)
	{
		commands.remove(command);
	}

	// 执行所有命令的发送
	void Execute()
	{
		list<Command*>::iterator iter = commands.begin();
		for (; iter != commands.end(); ++iter)
		{
			(*iter)->Execute();
		}
	}

private:
	list<Command*> commands;
};

/* The Receiver class */
class Light {
public:
	void TurnOn()
	{
		cout << "The light is on" << endl;
	}

	void TurnOff()
	{
		cout << "The light is off" << endl;
	}
};

/* The Command for turning on the light - ConcreteCommand #1 */
class FlipUpCommand : public Command {
public:
	FlipUpCommand(Light light)
	{
		light = light;
	}

	void Execute()
	{
		light.TurnOn();
	}
private:
	Light light;	// 命令中包含命令接收者
};

/* The Command for turning off the light - ConcreteCommand #2 */
class FlipDownCommand : public Command {
public:
	FlipDownCommand(Light light)
	{
		light = light;
	}

	void Execute()
	{
		light.TurnOff();
	}
private:
	Light light;	// 命令中包含命令接收者
};

int main()
{
	Light light;	// 灯有‘开’、‘关’两种操作
	Command *up = new FlipUpCommand(light);		// ‘开’命令
	Command *down = new FlipDownCommand(light);	// ‘关’命令
	Switch sw;

	sw.Add(up);		// 命令交给开关
	sw.Add(down);	// 命令交给开关
	sw.Execute();	// 开关执行命令

	sw.Remove(up);
	sw.Execute();	// 开关执行命令


	system("pause");
	return 0;
}

运行结果:


命令被封装成类,然后由某个Invoker(这里是switch开关类)保存、删除、发出命令。命令行的优点在于:把请求一个操作的对象(Invoker)与知道怎么执行一个操作的对象(Receiver)分隔开了。我们可以在实际操作开始之前或之后进行某些灵活的操作,比如:添加、删除、重复、记录日志等。


参考:

维基百科

《大话设计模式》第23章