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