23 命令模式

在面向对象程序设计里,有时需用专门的command类封装对象调用过程。命令模式将请求或操作封装到对象,分隔发出与执行命令的责任。它能降低系统耦合度,便于添加新命令,但可能使系统有过多具体命令类,还给出类图、示例代码及运行结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在面向对象的程序设计中,一个对象调用另一个对象,一般情况下的调用过程是:
创建目标对象实例;设置调用参数;调用目标对象的方法。
但在有些情况下有必要使用一个专门的类对这种调用过程加以封装,我们把这种专门的类称作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;
}

运行结果如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Chiang木

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

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

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

打赏作者

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

抵扣说明:

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

余额充值