27.1 策略模式 VS 命令模式
27.1.1 策略模式实现压缩算法
//行为型模式大PK——策略模式和命令模式 //实例:用策略模式实现压缩算法 #include <iostream> #include <string> using namespace std; //抽象压缩算法 class Algorithm { public: //压缩算法 virtual bool compress(string source, string to) = 0; //解压算法 virtual bool uncompress(string source, string to) = 0; virtual ~Algorithm(){} }; //具体算法:zip算法 class Zip : public Algorithm { public: //zip格式的压缩算法 bool compress(string source, string to) { cout << source << " --> " << to <<" ZIP压缩成功" <<endl; return true; } //zip格式的解压缩算法 bool uncompress(string source, string to) { cout << source <<" --> " << to <<" ZIP解压缩成功" <<endl; return true; } }; //具体算法:Gzip class Gzip : public Algorithm { public: //gzip格式的压缩算法 bool compress(string source, string to) { cout << source << " --> " << to <<" GZIP压缩成功" <<endl; return true; } //gzip格式的解压缩算法 bool uncompress(string source, string to) { cout << source <<" --> " << to <<" GZIP解压缩成功" <<endl; return true; } }; //环境角色 class Context { private: Algorithm* al; //指向抽象算法 public: Context(Algorithm* al) { this->al = al; } //设置算法策略 void setAlgorithm(Algorithm* al) { this->al = al; } //执行压缩算法 bool compress(string source, string to) { return al->compress(source ,to); } //执行解压缩算法 bool uncompress(string source, string to) { return al->uncompress(source ,to); } }; int main() { //创建两种算法策略 Algorithm* alZip = new Zip(); Algorithm* alGzip = new Gzip(); //创建环境角色,并执行zip算法 Context ctx(alZip); cout <<"========执算zip算法========" << endl; //执行压缩算法 ctx.compress("c:\\window", "d:\\windows.zip"); //执行解压缩算法 ctx.compress("c:\\window.zip", "d:\\windows"); //"========执算gzip算法========" cout <<"========执算gzip算法========" << endl; //更换算法 ctx.setAlgorithm(alGzip); //执行压缩算法 ctx.compress("c:\\window", "d:\\windows.zip"); //执行解压缩算法 ctx.compress("c:\\window.zip", "d:\\windows"); delete alZip; delete alGzip; return 0; }; /*输出结果: ========执算zip算法======== c:\window --> d:\windows.zip ZIP压缩成功 c:\window.zip --> d:\windows ZIP压缩成功 ========执算gzip算法======== c:\window --> d:\windows.zip GZIP压缩成功 c:\window.zip --> d:\windows GZIP压缩成功 */
27.1.2 命令模式实现压缩算法
注意:图中的接收者是按功能设计的
//行为型模式大PK——策略模式和命令模式 //实例:用命令模式实现压缩算法 #include <iostream> #include <string> using namespace std; //抽象接收者 class IReceiver { public: //压缩 virtual bool compress(string source, string to) = 0; //解压 virtual bool uncompress(string source, string to) = 0; virtual ~IReceiver(){} }; //zip接收者 class ZipReceiver : public IReceiver { public: //压缩 bool compress(string source, string to) { cout << source << " --> " << to <<" ZIP压缩成功" <<endl; return true; } //解压 bool uncompress(string source, string to) { cout << source << " --> " << to <<" ZIP解压缩成功" <<endl; return true; } }; //Gzip接收者 class GzipReceiver : public IReceiver { public: //压缩 bool compress(string source, string to) { cout << source << " --> " << to <<" GZIP压缩成功" <<endl; return true; } //解压 bool uncompress(string source, string to) { cout << source << " --> " << to <<" GZIP解压缩成功" <<endl; return true; } }; //抽象压缩命令 class AbstractCmd { protected: //持有接收者的引用 IReceiver* zip; IReceiver* gzip; public: AbstractCmd() { zip = new ZipReceiver(); gzip = new GzipReceiver(); } virtual ~AbstractCmd() { delete zip; delete gzip; } //抽象方法,命令的具体单元 virtual bool execute(string source, string to) = 0; }; //zip压缩命令 class ZipCompressCmd : public AbstractCmd { public: bool execute(string source, string to) { return zip->compress(source, to); } }; //zip解压缩命令 class ZipUncompressCmd : public AbstractCmd { public: bool execute(string source, string to) { return zip->uncompress(source, to); } }; //gzip压缩命令 class GzipCompressCmd : public AbstractCmd { public: bool execute(string source, string to) { return gzip->compress(source, to); } }; //gzip解压缩命令 class GzipUncompressCmd : public AbstractCmd { public: bool execute(string source, string to) { return gzip->uncompress(source, to); } }; //调用者 class Invoker { private: //持有抽象命令的引用 AbstractCmd* cmd; public: Invoker(AbstractCmd* cmd) { this->cmd = cmd; } //执行命令 bool execute(string source, string to) { return cmd->execute(source, to); } void setCommand(AbstractCmd* cmd) { this->cmd = cmd; } }; int main() { //定义一个命令,压缩一个文件 AbstractCmd* cmd = new ZipCompressCmd(); //AbstractCmd* cmd = new ZipUncompressCmd();//换命令 //定义调用者 Invoker* invoker = new Invoker(cmd); //执行压缩命令 cout <<"========执行压缩命令========"<<endl; invoker->execute("c:\\windows", "d:\\windows.zip"); return 0; }; /*输出结果: ========执行压缩命令======== c:\windows --> d:\windows.zip ZIP压缩成功 */
//另一种实现(只提供类图)
注意:图中的接收者是按对象设计的
27.1.3 小结
(1)当命令模式退化时,比如无接收者(接收者非常简单,无需专门编写一个接收者),在这种情况下,命令模式和策略模式的类图完全一样,代码实现也比较类似
(2)关注点不同
①策略模式关注的是算法替换的问题,一个新的算法投产,旧算法退体,或者提供多种算法由调用者自己选择使用,算法的自由更替是它实现的要点。换句话说,策略模式关注的是算法的完整性、封装性,只有具备了这两个条件才能保证其可以自由切换。
②命令模式则关注的是解耦问题,如何让请求者和执行者解耦是它需要首先解决的,解耦的要求就是把请求的内容封装为一个个命令,由接收者执行。由于封装成命令,就同时可以对命令进行多种处理,例如撤销、记录等。
(3)角色功能不同
①策略模式中的具体算法是负责一个完整算法逻辑,它是不可再拆分的原子业务,一旦变更就是对算法整体的变更。
②命令模式它关注命令的实现,也就是功能的实现。接收者对命令负责,而与请求者无关。
(4)使用场景不同
策略模式适用于算法要求变换的场景,而命令模式适用于解耦两个有紧耦合的对象。
时间: 2024-10-17 10:47:47