设计模式之禅之行为类PK【命令模式VS策略模式】

设计模式之禅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版;
  • 仅供学习,严禁商业用途;
  • 代码手写,没有经编译器编译,有个别错误,自行根据上下文改正;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乘风御浪云帆之上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值