设计模式之禅之行为类PK【策略模式VS状态模式】 爱被打了一巴掌 2022-06-02 12:07 188阅读 0赞 # 设计模式之禅PK之行为类 # ### 行为类设计模式 ### * 行为类模式: * 责任链模式 * 命令模式 * 迭代器模式 * 中介者模式 * 备忘录模式 * 观察者模式 * 状态模式 * 策略模式 * 模板方法模式 * 访问者模式 ### 【策略模式】VS【状态模式】 ### * 在行为类设计模式中,状态模式和策略模式是亲兄弟,两者都非常的相似。那先看看他们的不同吧 ### 类图 ### <table style="margin-top:15px; margin-right:0px; margin-bottom:15px; margin-left:0px; padding-top:0px; padding-right:0px; padding-bottom:0px; padding-left:0px; border-top-width:0px; border-right-width:0px; border-bottom-width:0px; border-left-width:0px; border-style:initial; border-color:initial"> <thead style="margin-top:0px; margin-right:0px; margin-bottom:0px; margin-left:0px; padding-top:0px; padding-right:0px; padding-bottom:0px; padding-left:0px; border-top-width:0px; border-right-width:0px; border-bottom-width:0px; border-left-width:0px; border-style:initial; border-color:initial"> <tr style="margin:0px; padding:0px; border-width:1px 0px 0px; border-right-style:initial; border-bottom-style:initial; border-left-style:initial; border-right-color:initial; border-bottom-color:initial; border-left-color:initial; border-top-style:solid; border-top-color:rgb(204,204,204)"> <th style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">策略模式</th> <th style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">状态模式</th> </tr> </thead> <tbody style="margin-top:0px; margin-right:0px; margin-bottom:0px; margin-left:0px; padding-top:0px; padding-right:0px; padding-bottom:0px; padding-left:0px; border-top-width:0px; border-right-width:0px; border-bottom-width:0px; border-left-width:0px; border-style:initial; border-color:initial"> <tr style="margin:0px; padding:0px; border-width:1px 0px 0px; border-right-style:initial; border-bottom-style:initial; border-left-style:initial; border-right-color:initial; border-bottom-color:initial; border-left-color:initial; border-top-style:solid; border-top-color:rgb(204,204,204)"> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)"><img src="https://i.imgur.com/HbJmOYZ.png" alt="" style="margin-right:0px; margin-bottom:0px; margin-left:0px; padding:0px; border-width:0px; border-style:initial; border-color:initial; max-width:100%"></td> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)"><img src="https://i.imgur.com/Z2lRrD5.png" alt="" style="margin-right:0px; margin-bottom:0px; margin-left:0px; padding:0px; border-width:0px; border-style:initial; border-color:initial; max-width:100%"></td> </tr> </tbody> </table> * 两个类图非常的相似,都是通过Context类封装一个具体的行为,都提供了一个封装的方法,是高扩展的设计模式。根据两个模式的定义,看看这两者的区别 <table style="margin-top:15px; margin-right:0px; margin-bottom:15px; margin-left:0px; padding-top:0px; padding-right:0px; padding-bottom:0px; padding-left:0px; border-top-width:0px; border-right-width:0px; border-bottom-width:0px; border-left-width:0px; border-style:initial; border-color:initial"> <thead style="margin-top:0px; margin-right:0px; margin-bottom:0px; margin-left:0px; padding-top:0px; padding-right:0px; padding-bottom:0px; padding-left:0px; border-top-width:0px; border-right-width:0px; border-bottom-width:0px; border-left-width:0px; border-style:initial; border-color:initial"> <tr style="margin:0px; padding:0px; border-width:1px 0px 0px; border-right-style:initial; border-bottom-style:initial; border-left-style:initial; border-right-color:initial; border-bottom-color:initial; border-left-color:initial; border-top-style:solid; border-top-color:rgb(204,204,204)"> <th style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">区别项</th> <th style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">策略模式</th> <th style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">状态模式</th> </tr> </thead> <tbody style="margin-top:0px; margin-right:0px; margin-bottom:0px; margin-left:0px; padding-top:0px; padding-right:0px; padding-bottom:0px; padding-left:0px; border-top-width:0px; border-right-width:0px; border-bottom-width:0px; border-left-width:0px; border-style:initial; border-color:initial"> <tr style="margin:0px; padding:0px; border-width:1px 0px 0px; border-right-style:initial; border-bottom-style:initial; border-left-style:initial; border-right-color:initial; border-bottom-color:initial; border-left-color:initial; border-top-style:solid; border-top-color:rgb(204,204,204)"> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">封装的对象</td> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">封装的是不同的算法,算法之间没有交互,已达到算法可以自由切换的目的</td> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">封装的是不同的状态,已达到状态切换为之发生改变的目的,</td> </tr> <tr style="margin-top:0px; margin-right:0px; margin-bottom:0px; margin-left:0px; padding-top:0px; padding-right:0px; padding-bottom:0px; padding-left:0px; border-top-width:1px; border-right-width:0px; border-bottom-width:0px; border-left-width:0px; border-style:initial; border-color:initial; border-top-style:solid; border-top-color:rgb(204,204,204); background-color:rgb(248,248,248)"> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">目标</td> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">不同的人生阶段,有着不同的生活方式:小时候玩耍、成人时期的工作和老年的享受天伦之乐----之间用到的算法大概有这么几种:冒泡排序、快速排序、插入排序。。。</td> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">状态的模式:人的一生的状态---儿童、成人、老人</td> </tr> </tbody> </table> ### 以人生的实现来将代码码一下 ### * 还是先来看看两者的类图吧 <table style="margin-top:15px; margin-right:0px; margin-bottom:15px; margin-left:0px; padding-top:0px; padding-right:0px; padding-bottom:0px; padding-left:0px; border-top-width:0px; border-right-width:0px; border-bottom-width:0px; border-left-width:0px; border-style:initial; border-color:initial"> <thead style="margin-top:0px; margin-right:0px; margin-bottom:0px; margin-left:0px; padding-top:0px; padding-right:0px; padding-bottom:0px; padding-left:0px; border-top-width:0px; border-right-width:0px; border-bottom-width:0px; border-left-width:0px; border-style:initial; border-color:initial"> <tr style="margin:0px; padding:0px; border-width:1px 0px 0px; border-right-style:initial; border-bottom-style:initial; border-left-style:initial; border-right-color:initial; border-bottom-color:initial; border-left-color:initial; border-top-style:solid; border-top-color:rgb(204,204,204)"> <th style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">策略模式</th> <th style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">状态模式</th> </tr> </thead> <tbody style="margin-top:0px; margin-right:0px; margin-bottom:0px; margin-left:0px; padding-top:0px; padding-right:0px; padding-bottom:0px; padding-left:0px; border-top-width:0px; border-right-width:0px; border-bottom-width:0px; border-left-width:0px; border-style:initial; border-color:initial"> <tr style="margin:0px; padding:0px; border-width:1px 0px 0px; border-right-style:initial; border-bottom-style:initial; border-left-style:initial; border-right-color:initial; border-bottom-color:initial; border-left-color:initial; border-top-style:solid; border-top-color:rgb(204,204,204)"> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)"><img src="https://i.imgur.com/weqCrjc.png" alt="" style="margin-right:0px; margin-bottom:0px; margin-left:0px; padding:0px; border-width:0px; border-style:initial; border-color:initial; max-width:100%"></td> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)"><img src="https://i.imgur.com/c2ad4ko.png" alt="" style="margin-right:0px; margin-bottom:0px; margin-left:0px; padding:0px; border-width:0px; border-style:initial; border-color:initial; max-width:100%"></td> </tr> </tbody> </table> * 策略模式实现人生 * 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(); } } * 执行结果 # # =====儿童的主要工作===== 儿童:玩耍! =====成人的主要工作===== 成年:工作! =====老年的主要工作===== 老年:享受天伦之乐! * 运行结果与策略模式相同,但是两者的分析角度是大相径庭的。策略模式的实现是通过分析每个人的工作方式的不同而得出三个不同的算法逻辑;状态模式则是从人的生长规律来分析,每个状态对应了不同的行为,状态改变后行为也随之改变 ### 最佳实践 ### * 从上述的例子中不难看出,策略模式和状态模式称之为兄弟也不为过,但是这两者还是存在着非常大的差别,而且也是很容易区分的 <table style="margin-top:15px; margin-right:0px; margin-bottom:15px; margin-left:0px; padding-top:0px; padding-right:0px; padding-bottom:0px; padding-left:0px; border-top-width:0px; border-right-width:0px; border-bottom-width:0px; border-left-width:0px; border-style:initial; border-color:initial"> <thead style="margin-top:0px; margin-right:0px; margin-bottom:0px; margin-left:0px; padding-top:0px; padding-right:0px; padding-bottom:0px; padding-left:0px; border-top-width:0px; border-right-width:0px; border-bottom-width:0px; border-left-width:0px; border-style:initial; border-color:initial"> <tr style="margin:0px; padding:0px; border-width:1px 0px 0px; border-right-style:initial; border-bottom-style:initial; border-left-style:initial; border-right-color:initial; border-bottom-color:initial; border-left-color:initial; border-top-style:solid; border-top-color:rgb(204,204,204)"> <th style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">比较项</th> <th style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">策略模式</th> <th style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">装饰模式</th> </tr> </thead> <tbody style="margin-top:0px; margin-right:0px; margin-bottom:0px; margin-left:0px; padding-top:0px; padding-right:0px; padding-bottom:0px; padding-left:0px; border-top-width:0px; border-right-width:0px; border-bottom-width:0px; border-left-width:0px; border-style:initial; border-color:initial"> <tr style="margin:0px; padding:0px; border-width:1px 0px 0px; border-right-style:initial; border-bottom-style:initial; border-left-style:initial; border-right-color:initial; border-bottom-color:initial; border-left-color:initial; border-top-style:solid; border-top-color:rgb(204,204,204)"> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">环境角色的职责</td> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">只是一个委托作用,负责算法的替换</td> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">不仅仅是委托行为,它还具有登记状态变化的功能,与具体的状态类协作,共同完成状态切换行为为随之切换的任务</td> </tr> <tr style="margin-top:0px; margin-right:0px; margin-bottom:0px; margin-left:0px; padding-top:0px; padding-right:0px; padding-bottom:0px; padding-left:0px; border-top-width:1px; border-right-width:0px; border-bottom-width:0px; border-left-width:0px; border-style:initial; border-color:initial; border-top-style:solid; border-top-color:rgb(204,204,204); background-color:rgb(248,248,248)"> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">解决的问题重点</td> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">解决内部算法如何改变的问题--将内部算法的改变时对外界的影响降到最低,它是保证算法可以自由的切换</td> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">解决内在状态的改变而引起行为改变的问题,它的出发点是事务的状态,封装状态而暴露行为,一个对象状态的改变,从外界看就像是行为的改变</td> </tr> <tr style="margin:0px; padding:0px; border-width:1px 0px 0px; border-right-style:initial; border-bottom-style:initial; border-left-style:initial; border-right-color:initial; border-bottom-color:initial; border-left-color:initial; border-top-style:solid; border-top-color:rgb(204,204,204)"> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">解决问题的方法</td> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">确保算法可以自由切换,但是什么时候用算法它决定不了</td> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">对外暴露的行为,状态的变化一般是由环境角色和具体的状态共同完成的,也就是说状态模式封装了状态的变化而暴露了不同的行为或行为结果</td> </tr> <tr style="margin-top:0px; margin-right:0px; margin-bottom:0px; margin-left:0px; padding-top:0px; padding-right:0px; padding-bottom:0px; padding-left:0px; border-top-width:1px; border-right-width:0px; border-bottom-width:0px; border-left-width:0px; border-style:initial; border-color:initial; border-top-style:solid; border-top-color:rgb(204,204,204); background-color:rgb(248,248,248)"> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">应用场景</td> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">可以是一个有意义的对象;也可以是无意义的逻辑片段。【eg:MD5加密,DES算法,RSA算法】</td> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">一系列状态变化的场景,要求一个对象必须具有二维【状态和行为】</td> </tr> <tr style="margin:0px; padding:0px; border-width:1px 0px 0px; border-right-style:initial; border-bottom-style:initial; border-left-style:initial; border-right-color:initial; border-bottom-color:initial; border-left-color:initial; border-top-style:solid; border-top-color:rgb(204,204,204)"> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">复杂度不同</td> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">结构比较简单,扩展比较容易</td> <td style="margin:0px; padding:6px 13px; border-color:rgb(204,204,204)">通常比较复杂</td> </tr> </tbody> </table> ### 声明 ### * 摘自秦小波《设计模式之禅》第2版; * 仅供学习,严禁商业用途; * 代码手写,没有经编译器编译,有个别错误,自行根据上下文改正;
相关 设计模式之禅之跨战区PK【策略模式VS桥梁模式】 设计模式之禅跨战区PK 前言 创建类模式描述如何创建对象 行为类模式关注如何管理对象的行为 结构类模式则侧重于如何建立一个软件结构 实际的应 我不是女神ヾ/ 2022年06月02日 12:26/ 0 赞/ 205 阅读
相关 设计模式之禅之结构类PK【装饰模式VS适配器模式】 设计模式之禅PK之结构类 结构类设计模式 结构类模式: 适配器模式 桥梁模式 组合模式 装饰 不念不忘少年蓝@/ 2022年06月02日 12:26/ 0 赞/ 170 阅读
相关 设计模式之禅之结构类PK【代理模式VS装饰模式】 设计模式之禅PK之结构类 结构类设计模式 结构类模式: 适配器模式 桥梁模式 组合模式 装饰 Bertha 。/ 2022年06月02日 12:25/ 0 赞/ 185 阅读
相关 设计模式之禅之行为类PK【观察者模式VS责任链模式】 设计模式之禅PK之行为类 行为类设计模式 行为类模式: 责任链模式 命令模式 迭代器模式 中 悠悠/ 2022年06月02日 12:07/ 0 赞/ 195 阅读
相关 设计模式之禅之行为类PK【策略模式VS状态模式】 设计模式之禅PK之行为类 行为类设计模式 行为类模式: 责任链模式 命令模式 迭代器模式 中 爱被打了一巴掌/ 2022年06月02日 12:07/ 0 赞/ 189 阅读
相关 设计模式之禅之行为类PK【命令模式VS策略模式】 设计模式之禅PK之行为类 行为类设计模式 行为类模式: 责任链模式 命令模式 迭代器模式 中 红太狼/ 2022年06月02日 12:07/ 0 赞/ 154 阅读
相关 设计模式之禅之创建类PK【抽象工厂模式VS建造者模式】 设计模式之禅PK之创建类 创建类设计模式 创建类模式: 工厂方法模式 建造者模式 抽象工厂模式 矫情吗;*/ 2022年06月02日 12:07/ 0 赞/ 173 阅读
相关 设计模式之禅之创建类PK【工厂模式VS建造者模式】 设计模式之禅PK之创建类 创建类设计模式 创建类模式: 工厂方法模式 建造者模式 抽象工厂模式 ﹏ヽ暗。殇╰゛Y/ 2022年06月02日 12:07/ 0 赞/ 225 阅读
相关 设计模式之禅【状态模式】 真刀实枪之状态模式 从电梯说起 随着城市的发展,有两样东西的发明在城市的发展中起到非常重要的作用 1. 深碍√TFBOYSˉ_/ 2022年06月02日 11:59/ 0 赞/ 189 阅读
相关 设计模式之禅【策略模式】 真刀实枪之策略模式 刘备江东娶妻,赵云他容易吗? “在三国演义中,最佩服诸葛亮的地方不是因为他未出茅庐而三分天下的预测,也不是他在赤壁鏖战中 ﹏ヽ暗。殇╰゛Y/ 2022年06月02日 10:50/ 0 赞/ 235 阅读
还没有评论,来说两句吧...