在面向对象的程序设计中,一个对象调用另一个对象,一般情况下的调用过程是:
创建目标对象实例;设置调用参数;调用目标对象的方法。
但在有些情况下有必要使用一个专门的类对这种调用过程加以封装,我们把这种专门的类称作command类。命令模式就是把一个请求或操作封装到一个对象中,把发出命令的责任和执行命令的责任分隔开,委派给不同的对象。

优点: 1、降低了系统耦合度。 2、新的命令可以很容易添加到系统中去。

缺点:使用命令模式可能会导致某些系统有过多的具体命令类。

类图如下:

示例代码如下:

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

/* 小贩类,可以卖水果 */
class Vendor
{
public:
	void saleBanana()
	{
		std::cout << "卖香蕉" << std::endl;
	}
	void saleApple()
	{
		std::cout << "卖苹果" << std::endl;
	}
};

/* 抽象命令基类 */
class Command
{
public:
	virtual void sale() = 0;
	virtual ~Command() {}
};

/* 具体卖香蕉命令子类 */
class BananaCommand : public Command
{
public:
	BananaCommand(Vendor * v)
	{
		m_v = v;
	}
	virtual void sale() 
	{
		m_v->saleBanana();
	}
private:
	Vendor * m_v;
};

/* 具体卖苹果命令子类 */
class AppleCommand : public Command
{
public:
	AppleCommand(Vendor * v)
	{
		m_v = v;
	}

	virtual void sale() 
	{
		m_v->saleApple();
	}
private:
	Vendor * m_v;
};

/* 服务员类 */
class Waiter
{
public:
	void setCommand(Command * c)
	{
		m_command = c;
	}
	void sale()
	{
		m_command->sale();
	}
private:
	Command * m_command;
};

/* 批量处理命令类 */
class AdvWaiter
{
public:
	AdvWaiter()
	{
		m_list = new std::list<Command *>;
		m_list->clear();
	}
	~AdvWaiter()
	{
		delete m_list;
		m_list = nullptr;
	}

	/* 添加新的命令 */
	void setCommands(Command * c)
	{
		m_list->push_back(c);
	}

	void sale()
	{
		/* 执行list中的所有命令 */
		for (std::list<Command *>::iterator it = m_list->begin(); it != m_list->end(); it++)
		{
			(*it)->sale();
		}
	}

private:
	std::list<Command *> * m_list;
};

void mytest()
{
	std::cout << "小商贩 直接 卖 水果" << std::endl;
	Vendor * v1 = new Vendor();
	v1->saleApple();
	v1->saleBanana();
	std::cout <<"------------------------------------------------" << std::endl;
	delete v1;
	v1 = NULL;

	std::cout << "小商贩 通过命令 卖 水果" << std::endl;
	Vendor * v2 = new Vendor();
	AppleCommand * ac2 = new AppleCommand(v2);
	ac2->sale();
	BananaCommand * bc2 = new BananaCommand(v2);
	bc2->sale();
	std::cout << "------------------------------------------------" << std::endl;
	delete bc2;
	bc2 = NULL;
	delete ac2;
	ac2 = NULL;
	delete v2;
	v2 = NULL;

	std::cout << "小商贩 通过waiter 卖 水果" << std::endl;
	Vendor * v3 = new Vendor();
	AppleCommand *ac3 = new AppleCommand(v3);
	BananaCommand *bc3 = new BananaCommand(v3);
	Waiter *w3 = new Waiter();
	w3->setCommand(ac3);
	w3->sale();
	w3->setCommand(bc3);
	w3->sale();
	std::cout << "------------------------------------------------" << std::endl;
	delete w3;
	w3 = NULL;
	delete bc3;
	bc3 = NULL;
	delete ac3;
	ac3 = NULL;
	delete v3;
	v3 = NULL;

	std::cout << "小商贩 通过advwaiter 批量下单 卖水果" << std::endl;
	Vendor * v4 = new Vendor();
	AppleCommand * ac4 = new AppleCommand(v4);
	BananaCommand * bc4 = new BananaCommand(v4);
	AdvWaiter *w4 = new AdvWaiter();
	w4->setCommands(ac4);
	w4->setCommands(bc4);
	w4->sale();

	delete v4;
	v4 = NULL;
	delete w4;
	w4 = NULL;
	delete bc4;
	bc4 = NULL;
	delete ac4;
	ac4 = NULL;
	delete v4;
	v4 = NULL;

	return;
}


int main()
{
	mytest();

	system("pause");
	return 0;
}

运行结果如下: