设计模式之禅PK之行为类
行为类设计模式
- 行为类模式:
- 责任链模式
- 命令模式
- 迭代器模式
- 中介者模式
- 备忘录模式
- 观察者模式
- 状态模式
- 策略模式
- 模板方法模式
- 访问者模式
【命令模式】VS【策略模式】
- 命令模式和策略模式的类图确实很相似,只是命令模式多了一个接受者(Receiver)角色
- 两者的区别
不同点 | 命令模式 | 策略模式 |
---|---|---|
意图 | 对动作的解耦,把一个动作的执行分为执行对象(执行者)、执行行为(命令角色)、让两者相互独立而不互相影响 | 封装算法,他认为“算法”已经是一个完整的、不可分割的原子任务,这些算法独立,并且可以相互替换,这些行为的变化独立于拥有拥有行为的客户 |
- 从压缩文件继续PK
- zip压缩/解压缩【Windows操作系统常用的压缩方法】
- gzip压缩/解压缩【Linus常用的压缩方法】
类图对比
策略模式实现压缩算法 | 命令模式实现压缩算法 |
---|---|
代码具体实现
-
策略模式代码
-
Algorithm
package com.peng.pk_cl; /** * @author kungfu~peng * @data 2017年12月13日 * @description */ public interface Algorithm { // 压缩算法 public boolean compress(String source, String to); // 解压算法 public boolean uncompress(String source, String to); }
-
Zip
package com.peng.pk_cl; /** * @author kungfu~peng * @data 2017年12月13日 * @description */ public class Zip implements Algorithm { @Override public boolean compress(String source, String to) { System.out.println(source + "====>>zip压缩成功!======>>" + to); return true; } @Override public boolean uncompress(String source, String to) { System.out.println(source + "====>>zip解压缩成功!======>>" + to); return true; } }
-
Gzip
package com.peng.pk_cl; /** * @author kungfu~peng * @data 2017年12月13日 * @description */ public class Gzip implements Algorithm { @Override public boolean compress(String source, String to) { System.out.println(source + "====>>Gzip压缩成功!======>>" + to); return true; } @Override public boolean uncompress(String source, String to) { System.out.println(source + "====>>Gzip解压缩成功!======>>" + to); return true; } }
-
Context
package com.peng.pk_cl; /** * @author kungfu~peng * @data 2017年12月13日 * @description */ public class Context { // 指向抽象算法 private Algorithm al; // 构造函数传递具体的算法 public Context(Algorithm al) { super(); this.al = al; } // 执行压缩算法 public boolean compress(String source, String to) { return al.compress(source, to); } // 执行解压缩算法 public boolean uncompress(String source, String to) { return al.uncompress(source, to); } }
-
Client
package com.peng.pk_cl; /** * @author kungfu~peng * @data 2017年12月13日 * @description */ public class Client { public static void main(String[] args) { // 定义环境角色 Context context; // 执行zip的压缩算法 System.out.println("====对文件执行zip压缩算法====="); context = new Context(new Zip()); context.compress("a.txt", "a.txt.zip"); // 执行zip的解压缩算法 System.out.println("====对文件执行zip解压缩算法====="); context = new Context(new Zip()); context.uncompress("a.txt.zip", "a.txt"); // 执行Gzip的压缩算法 System.out.println("====对文件执行gZip压缩算法====="); context = new Context(new Gzip()); context.compress("a.txt", "a.txt.gzip"); // 执行zip的解压缩算法 System.out.println("====对文件执行Gzip解压缩算法====="); context = new Context(new Gzip()); context.uncompress("a.txt.gzip", "a.txt"); } }
-
执行结果
====对文件执行zip压缩算法===== a.txt====>>zip压缩成功!======>>a.txt.zip ====对文件执行zip解压缩算法===== a.txt.zip====>>zip解压缩成功!======>>a.txt ====对文件执行gZip压缩算法===== a.txt====>>Gzip压缩成功!======>>a.txt.gzip ====对文件执行Gzip解压缩算法===== a.txt.gzip====>>Gzip解压缩成功!======>>a.txt
-
-
命令模式代码
-
AbstractCmd
package com.peng.pk_ml; /** * @author kungfu~peng * @data 2017年12月13日 * @description */ public abstract class AbstractCmd { // 对接收者的引用 protected IReceiver zip = new ZipReceiver(); protected IReceiver gzip = new GzipReceiver(); // 抽象方法,命令的具体单元 public abstract boolean execute(String source, String to); }
-
ZipCompressCmd
package com.peng.pk_ml; /** * @author kungfu~peng * @data 2017年12月14日 * @description */ public class ZipCompressCmd extends AbstractCmd { @Override public boolean execute(String source, String to) { return super.zip.compress(source, to); } }
-
ZipUncompressCmd
package com.peng.pk_ml; /** * @author kungfu~peng * @data 2017年12月14日 * @description */ public class ZipUncompressCmd extends AbstractCmd { @Override public boolean execute(String source, String to) { return super.zip.uncompress(source, to); } }
-
GzipCompressCmd
package com.peng.pk_ml; /** * @author kungfu~peng * @data 2017年12月14日 * @description */ public class GzipCompressCmd extends AbstractCmd { @Override public boolean execute(String source, String to) { return super.gzip.compress(source, to); } }
-
GzipUncompressCmd
package com.peng.pk_ml; /** * @author kungfu~peng * @data 2017年12月14日 * @description */ public class GzipUncompressCmd extends AbstractCmd { @Override public boolean execute(String source, String to) { return super.gzip.uncompress(source, to); } }
-
IReceiver
package com.peng.pk_ml; /** * @author kungfu~peng * @data 2017年12月14日 * @description */ public interface IReceiver { // 压缩 public boolean compress(String source, String to); // 解压缩 public boolean uncompress(String source, String to); }
-
ZipReceiver
package com.peng.pk_ml; /** * @author kungfu~peng * @data 2017年12月14日 * @description */ public class ZipReceiver implements IReceiver { @Override public boolean compress(String source, String to) { System.out.println(source + "=====》压缩=====》" + to); return true; } @Override public boolean uncompress(String source, String to) { System.out.println(source + "=====》解压缩=====》" + to); return true; } }
-
GzipReceiver
package com.peng.pk_ml; /** * @author kungfu~peng * @data 2017年12月14日 * @description */ public class GzipReceiver implements IReceiver { @Override public boolean compress(String source, String to) { System.out.println(source + "=====》压缩=====》" + to); return true; } @Override public boolean uncompress(String source, String to) { System.out.println(source + "=====》解压缩=====》" + to); return true; } }
-
Invoker
package com.peng.pk_ml; /** * @author kungfu~peng * @data 2017年12月14日 * @description */ public class Invoker { // 抽象命令的引用 public AbstractCmd cmd; public Invoker(AbstractCmd cmd) { super(); this.cmd = cmd; } // 执行命令 public boolean execute(String source, String to) { return cmd.execute(source, to); } }
-
Client
package com.peng.pk_ml; /** * @author kungfu~peng * @data 2017年12月14日 * @description */ public class Client { public static void main(String[] args) { // 定义一个命令,压缩一个文件 AbstractCmd cmd = new ZipCompressCmd(); Invoker invoker = new Invoker(cmd); invoker.execute("a.txt", "a.txt.zip"); // 解压缩 AbstractCmd cmd2 = new ZipUncompressCmd(); Invoker invoker2 = new Invoker(cmd2); invoker2.execute("a.txt.zip", "a.txt"); // 定义一个命令,压缩一个文件 AbstractCmd cmd3 = new GzipCompressCmd(); Invoker invoker3 = new Invoker(cmd3); invoker3.execute("a.txt", "a.txt.gzip"); // 解压缩 AbstractCmd cmd4 = new GzipUncompressCmd(); Invoker invoker4 = new Invoker(cmd4); invoker4.execute("a.txt.gzip", "a.txt"); } }
-
执行结果
a.txt=====》压缩=====》a.txt.zip a.txt.zip=====》解压缩=====》a.txt a.txt=====》压缩=====》a.txt.gzip a.txt.gzip=====》解压缩=====》a.txt
-
最佳实践
比较项 | 命令模式 | 策略模式 |
---|---|---|
关注点 | 关注的是解耦问题--把要求的内容封装成一个一个的命令【撤销、记录】 | 算法替换问题,关注算法的完整性,封装性 |
角色功能不同 | 关注命令的实现,也就是功能的实现 | 负责一个完整的算法--不可拆分的原子业务单元,一旦变更是对算法整体的变更 |
使用的场景 | 解耦两个有紧耦合关系的对象场合或者多命令撤销的场景 | 算法要求变换的场景 |
过程 | 关注了命令的封装,是请求者与执行者的彻底分开--相互之间互相独立,各自发展互不影响;命令模式可以排队处理;可以撤回 | 不可以排队和撤回---一次性操作即结束 |
声明
- 摘自秦小波《设计模式之禅》第2版;
- 仅供学习,严禁商业用途;
- 代码手写,没有经编译器编译,有个别错误,自行根据上下文改正;