// // // // // // // // //
///2013.2.25
// // // // // // // // //
花了一个多星期,
终于将三国志ⅢDS通关了。
从孑立之一禺,
索良才,修农商,盟良国,战四方。
以火攻,凭智取,明连锁,暗度仓。
禺鼠至群雄,
群雄至豪杰,
豪杰成霸主,
霸主而坐天下。
然而完成这一切,
笔者也未出茅庐,
——顶多只是上过几次茅庐而已。
科技时代,
真的是让古人无地自容了。
但是备哥哥在不知不觉之间,
却为后人设计程序提供了很好的思想方针。
据史书记载,
刘备总喜欢说这几句话:
"二弟,人手不够了,去征些兵吧"
"三弟,府里米粮不足,去买一些吧"
"诸葛先生,洒家近日略感不适,这些文书还是有劳你了"
"阿云,去帮我借本三国演义来看看吧,我不知道该怎么进行下一步了…"
“超哥,你去……”
所谓的君主范,
就是要做好一天不喝水也下下达三十多条命令的心理准备。
但是不管怎样,
命令还是被执行了,
兵征来了,米粮有了,文书批了,三国演义也借来了,超哥也去了……
命令发布者——刘备
命令——刘备的话
接受者——众人
这,
就是Command模式。
【核心】通过将命令与执行解耦,从而达到间接执行的目的。
UML图:
Command所做的事情,
就是通过Invoker唤醒Command从而使Receiver执行Action.
虽然听起来稍微有点绕,
但无疑这是一个最为标准的面向对象设计思想:
假如二弟不在身边,
刘备依然可以下达命令,
让别人去执行。
这简直就是解耦的模范示例。
示例代码
【大致思路】
Invoker唤醒Command从而使Command作用范围之内(此处即封装)的Receiver执行相应的命令。
Receiver.h
#ifndef _RECEIVER_H_ #define _RECEIVER_H_ #include<iostream> using namespace std; class Receiver { public: Receiver(){} ~Receiver(){} void executeFirstAction() { cout<<"Guan yu go to buy food."<<endl; } void executeSecondAction() { cout<<"Zhang fei go to recruit soldiers."<<endl; } }; #endif
Command.h
#ifndef _COMMAND_H_ #define _COMMAND_H_ class Receiver; class Command { public: Command(){} ~Command(){} virtual void Execute() = 0; }; class ConcreteCommand: public Command { public: typedef void (Receiver::* Action)(); ConcreteCommand(Receiver* r,Action a); ~ConcreteCommand(){} void Execute(); private: Receiver* rec; Action act; }; #endif
Command.cpp
#include"Command.h" #include"Receiver.h" ConcreteCommand::ConcreteCommand(Receiver* receiver,Action action) { rec =receiver; act = action; } void ConcreteCommand::Execute() { (rec->* act)(); }
Invoker.h
#ifndef _INVOKER_H_ #define _INVOKER_H_ #include"Command.h" class Invoker { public: Invoker(Command* command) { com = command; } ~Invoker(){} void Invoke() { com->Execute(); } private: Command* com; }; #endif
main.cpp
#include"Invoker.h" #include"Receiver.h" int main() { Receiver* receiver = new Receiver(); Command* commandToGuanYu = new ConcreteCommand(receiver,&Receiver::executeFirstAction); Command* commandToZhangFei = new ConcreteCommand(receiver,&Receiver::executeSecondAction); cout<<"First Command: "<<endl; Invoker* invoker = new Invoker(commandToGuanYu); invoker->Invoke(); cout<<endl; cout<<"Second Command: "<<endl; invoker = new Invoker(commandToZhangFei); invoker->Invoke(); return 0; }
输出结果:
【注意事项】
其实这里稍微用了一点点技巧,
使用了C++的函数指针。
该怎么解释这个东西呢?
应该说是与C#的委托很相似吧。
总之就是可以代表具有相同签名的函数的一个指针变量。
当然,
设计模式都是这样,
几乎没有一个设计模式是纯粹简单的代码集合,
更多时候是配合一些高级用法来使用的。
希望大家能够渐渐熟悉这些功能,
尽管没有被当做示例代码放在教科书中,
但是却是成熟代码中不可缺少的。
Know it,and get it.