命令模式是我们能够实现发送者和接收者之间的完全解耦,发送者是调用操作的对象,而接收者是接收请求并执行特定操作的对象。通过解耦,发送者无需了解接收者的接口。在这里,请求的含义是需要被执行的命令。
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。当将客户的单个请求封装成对象以后,我们就可以对这个请求存储更多的信息,使请求拥有更多的能力;命令模式能够把请求发送者和接收者解耦,使得命令发送者不用去关心请求将以何种方式被处理。
class Command; /*调用者(Invoker)*/ class Switch { public: Switch(){} ~Switch(){} void insertcommand(Command* pCom) { m_command.pus_back(pCom); } void excuteonce() { if (m_command.empty()) return; m_command.front()->excute(); m_command.pop_front(); } private: list< share_prt<Command*> > m_command; }; /*接收者(Recever)*/ class Appliance { public: Appliance(){} virtual ~Appliance(){} virtual bool start() = 0; virtual bool stop() = 0; }; class AirConditioner : public Appliance { public: AirConditioner(){} virtual ~AirConditioner(){} bool start() { cout <<"the air conditioner is on" << endl; } bool stop() { cout <<"the air conditioner is off" << endl; } }; class Fridge : public Appliance public: Fridge(){} virtual ~Fridge(){} bool On() { cout <<"the firdge is on" << endl; } bool Off() { cout <<"the firdge is off" << endl; } }; /*命令(Command)*/ class Command { public: Command(Appliance* pAl): m_pAlice(pAl){} virtual ~Command(){} virtual excute(); protected: Appliance* m_pAlice; }; class OnCommand : public Command { public: OnCommand(Appliance* pAl): Command(pAl){} virtual ~OnCommand(){} bool excute() { m_pAlice.On(); } }; class OffCommand : public Command { public: OffCommand(Appliance* pAl): Command(pAl){} virtual ~OffCommand(){} bool excute() { m_pAlice.Off(); } }; int main() { //接收者 AirConditioner air; Fridge fridge; //生成命令 OnCommand On1(&air); OnCommand On2(&fridge); OffCommand off1(&air); OffCommand off2(&fridge); //发送命令 Switch switcher; switcher.insertcommand(&on1); switcher.insertcommand(&on2); switcher.insertcommand(&off1); switcher.insertcommand(&off2); //执行命令 switcher.excuteonce(); switcher.excuteonce(); switcher.excuteonce(); switcher.excuteonce(); }
从如上的例子中可以分析出,调用者switch不会关心是开命令还是关命令,是属于空调的命令还是冰箱的命令,这样一方面可以做到解耦的效果,另一方面,还可以对接收者和命令进行方便的扩展,这就是命令模式的核心优点所在。当然缺点也正是如此,接收者和命令的组合数量是MxN的关系,再扩展是需要注意数量级的大小。
如对本文有疑问, 点击进行留言回复!!
软件设计模式六大原则-接口隔离原则 Interface Segregation Principle
设计模式之解释器模式(附:SpelExpressionParser中解释器模式应用分析)
网友评论