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