设计模式之禅之行为类PK【策略模式VS状态模式】

设计模式之禅PK之行为类

行为类设计模式

  • 行为类模式:
    • 责任链模式
    • 命令模式
    • 迭代器模式
    • 中介者模式
    • 备忘录模式
    • 观察者模式
    • 状态模式
    • 策略模式
    • 模板方法模式
    • 访问者模式

【策略模式】VS【状态模式】

  • 在行为类设计模式中,状态模式和策略模式是亲兄弟,两者都非常的相似。那先看看他们的不同吧

类图

策略模式状态模式
  • 两个类图非常的相似,都是通过Context类封装一个具体的行为,都提供了一个封装的方法,是高扩展的设计模式。根据两个模式的定义,看看这两者的区别
区别项策略模式状态模式
封装的对象封装的是不同的算法,算法之间没有交互,已达到算法可以自由切换的目的封装的是不同的状态,已达到状态切换为之发生改变的目的,
目标不同的人生阶段,有着不同的生活方式:小时候玩耍、成人时期的工作和老年的享受天伦之乐----之间用到的算法大概有这么几种:冒泡排序、快速排序、插入排序。。。状态的模式:人的一生的状态---儿童、成人、老人

以人生的实现来将代码码一下

  • 还是先来看看两者的类图吧
策略模式状态模式
  • 策略模式实现人生

    • WorkAlgorithm

      package com.peng.pk_cl2;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月14日
       * @description
       */
      public abstract class WorkAlgorithm {
          // 每个阶段都必须完成的任务
          public abstract void work();
      }
      
    • ChildWork

      package com.peng.pk_cl2;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月14日
       * @description
       */
      public class ChildWork extends WorkAlgorithm {
      
          @Override
          public void work() {
              System.out.println("儿童时期的工作是玩耍!");
          }
      
      }
      
    • AdultWork

      package com.peng.pk_cl2;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月14日
       * @description
       */
      public class AdultWork extends WorkAlgorithm {
          @Override
          public void work() {
              System.out.println("成年的任务是工作!");
          }
      
      }
      
    • OldWork

      package com.peng.pk_cl2;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月14日
       * @description
       */
      public abstract class WorkAlgorithm {
          // 每个阶段都必须完成的任务
          public abstract void work();
      }
      
    • Context

      package com.peng.pk_cl2;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月14日
       * @description
       */
      public class Context {
          private WorkAlgorithm workMethod;
      
          public WorkAlgorithm getWorkMethod() {
              return workMethod;
          }
      
          public void setWorkMethod(WorkAlgorithm workMethod) {
              this.workMethod = workMethod;
          }
      
          // 每个算法都必须具有的功能
          public void work() {
              workMethod.work();
          }
      
      }
      
    • Client

      package com.peng.pk_cl2;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月14日
       * @description
       */
      public class Client {
          public static void main(String[] args) {
              // 定义一个环境角色
              Context context = new Context();
              System.out.println("=====儿童的主要工作=====");
              context.setWorkMethod(new ChildWork());
              context.work();
      
              System.out.println("=====成年的主要工作=====");
              context.setWorkMethod(new AdultWork());
              context.work();
      
              System.out.println("=====老年的主要工作=====");
              context.setWorkMethod(new OldWork());
              context.work();
          }
      }
      
    • 执行结果

      =====儿童的主要工作=====
      儿童时期的工作是玩耍!
      =====成年的主要工作=====
      成年的任务是工作!
      =====老年的主要工作=====
      老年的任务是享受天伦之乐!
      
  • 状态模式实现人生

    • Human

      package comp.peng.pk_zt;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月14日
       * @description
       */
      public class Human {
          // 定义人都具有具备哪些状态
          public static final HumanState CHILD_STATE = new ChildrenState();
          public static final HumanState Adult_STATE = new AdultState();
          public static final HumanState Old_STATE = new OldState();
          // 定义一个人的状态
          private HumanState state;
      
          // 设置一个状态
          public void setState(HumanState state) {
              this.state = state;
          }
      
          // 人类的工作
          public void work() {
              this.state.work();
          }
      }
      
    • HumanState

      package comp.peng.pk_zt;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月14日
       * @description
       */
      public abstract class HumanState {
          // 指向一个具体的人
          protected Human human;
      
          // 设置一个具体的人
      
          public void setHuman(Human human) {
              this.human = human;
          }
      
          // 不管什么状态都要工作
          public abstract void work();
      }
      
    • ChildrenState

      package comp.peng.pk_zt;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月14日
       * @description
       */
      public class ChildrenState extends HumanState {
      
          @Override
          public void work() {
              System.out.println("儿童:玩耍!");
          }
      
      }
      
    • AdultStat

      package comp.peng.pk_zt;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月14日
       * @description 
       */
      public class AdultState extends HumanState{
      
          @Override
          public void work() {
              System.out.println("成年:工作!");
          }
      
      }
      
    • OldState

      package comp.peng.pk_zt;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月14日
       * @description
       */
      public class OldState extends HumanState {
      
          @Override
          public void work() {
              System.out.println("老年:享受天伦之乐!");
          }
      
      }
      
    • Client

      package comp.peng.pk_zt;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月14日
       * @description
       */
      public class Client {
          public static void main(String[] args) {
              // 定义一个普通的人
              Human human = new Human();
              // 设置一个初始状态
              human.setState(new ChildrenState());
              System.out.println("=====儿童的主要工作=====");
              human.work();
      
              // 设置一个初始状态
              human.setState(new AdultState());
              System.out.println("=====成人的主要工作=====");
              human.work();
      
              // 设置一个初始状态
              human.setState(new OldState());
              System.out.println("=====老年的主要工作=====");
              human.work();
          }
      }
      
    • 执行结果

      =====儿童的主要工作=====
      儿童:玩耍!
      =====成人的主要工作=====
      成年:工作!
      =====老年的主要工作=====
      老年:享受天伦之乐!
      
  • 运行结果与策略模式相同,但是两者的分析角度是大相径庭的。策略模式的实现是通过分析每个人的工作方式的不同而得出三个不同的算法逻辑;状态模式则是从人的生长规律来分析,每个状态对应了不同的行为,状态改变后行为也随之改变

最佳实践

  • 从上述的例子中不难看出,策略模式和状态模式称之为兄弟也不为过,但是这两者还是存在着非常大的差别,而且也是很容易区分的
比较项策略模式装饰模式
环境角色的职责只是一个委托作用,负责算法的替换不仅仅是委托行为,它还具有登记状态变化的功能,与具体的状态类协作,共同完成状态切换行为为随之切换的任务
解决的问题重点解决内部算法如何改变的问题--将内部算法的改变时对外界的影响降到最低,它是保证算法可以自由的切换解决内在状态的改变而引起行为改变的问题,它的出发点是事务的状态,封装状态而暴露行为,一个对象状态的改变,从外界看就像是行为的改变
解决问题的方法确保算法可以自由切换,但是什么时候用算法它决定不了对外暴露的行为,状态的变化一般是由环境角色和具体的状态共同完成的,也就是说状态模式封装了状态的变化而暴露了不同的行为或行为结果
应用场景可以是一个有意义的对象;也可以是无意义的逻辑片段。【eg:MD5加密,DES算法,RSA算法】一系列状态变化的场景,要求一个对象必须具有二维【状态和行为】
复杂度不同结构比较简单,扩展比较容易通常比较复杂

声明

  • 摘自秦小波《设计模式之禅》第2版;
  • 仅供学习,严禁商业用途;
  • 代码手写,没有经编译器编译,有个别错误,自行根据上下文改正;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

乘风御浪云帆之上

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

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

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

打赏作者

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

抵扣说明:

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

余额充值