head first 设计模式:策略模式

2023-11-09

策略模式:定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。 

(差不多应该是不固定模块的分离) 


当涉及“维护”时,为了“复用”(reuse)目的而使用继承,结局并不完美。


设计原则:
找出应用中可能需要变化之外,把他们独立出来,不要和那些不需要变化的代码混在一起。


把会变化的部分取出来“封装”起来,好让其他部分不会受到影响。
结果如何?代码变化引起的不经意后果变少,系统变得更有弹性。


把会变化的部分取出并合并封装起来,一遍以后可以轻易地改变活扩充此部分,而不影响不需要变化的部分。
这样的概念很简单,几乎是每个设计模块必须的军规。



针对接口编程,而不是针对实现编程。 

引入了一个新的概念:“行为”类。怎么说呢,就打里面鸭子的例子,把鸭子的飞行和叫的具体实现, 
再做一份基础的接口来,然后单独去实现,还能提高各种情况的复用性。 
如:
  1. public class Duck{  
  2.     QuackBehavior quackBehavior; //一个接口,也就是我们分离出来的行为接口  
  3.     public void performQuack(){  
  4.         quackBehavior.quck();//具体实现类是狗叫还是鸭子叫,是执行的时候才确定的,当然我们就可以利用spring或者ejb简单的来实现这种效果。  
  5.     }  
  6. }  

绿色的鸭子
  1. public class  MallardDuck extends Duck{  
  2.        public MallardDuck(){  
  3.            quackBehavior = new Quack();  
  4.             fly.....  
  5.        }  
  6. }  

关键在于,鸭子现在会将飞行和呱呱叫的动作“委托”(delegate)别人处理,而不是使用定义在duck类(或子类)内的呱呱叫和飞行方法。 

组合:行为不是继承而来的,而是和适当的行为对象“组合”来的。


设计原则:多用组合,少用继承。 

DEMO:
 

基本就是把鸭子的飞行和叫声单独抽取出来,然后在不改变鸭子类的前提下,还可以改变他的叫声和飞行。 

  1. package cn.partner4java.demo1.duck;  
  2.   
  3. /** 
  4. * 飞 
  5. * @author partner4java 
  6. * 
  7. */  
  8. public interface FlyBehavior {  
  9.     /** 
  10.      * 飞行动作 
  11.      */  
  12.     public void fly();  
  13. }  

  1. package cn.partner4java.demo1.duck;  
  2.   
  3. /** 
  4. * 叫声 
  5. * @author partner4java 
  6. * 
  7. */  
  8. public interface QuackBehavior {  
  9.     public void quack();  
  10. }  

  1. package cn.partner4java.demo1.duck;  
  2.   
  3. public abstract class Duck {  
  4.     protected FlyBehavior flyBehavior;  
  5.     protected QuackBehavior quackBehavior;  
  6.     public Duck(){  
  7.           
  8.     }  
  9.       
  10.     public abstract void display();  
  11.       
  12.     public void performFly(){  
  13.         flyBehavior.fly();  
  14.     }  
  15.       
  16.     public void performQuack(){  
  17.         quackBehavior.quack();  
  18.     }  
  19.       
  20.     public void swin(){  
  21.         System.out.println("All ducks float,even decoys!");  
  22.     }  
  23.       
  24.     public void setFlyBehavior(FlyBehavior flyBehavior) {  
  25.         this.flyBehavior = flyBehavior;  
  26.     }  
  27.     public void setQuackBehavior(QuackBehavior quackBehavior) {  
  28.         this.quackBehavior = quackBehavior;  
  29.     }  
  30.       
  31. }  

  1. package cn.partner4java.demo1.duck.impl;  
  2.   
  3. import cn.partner4java.demo1.duck.FlyBehavior;  
  4.   
  5. /** 
  6. * 不会飞 
  7. * @author partner4java 
  8. * 
  9. */  
  10. public class FlyNoWay implements FlyBehavior {  
  11.   
  12.     public void fly() {  
  13.         System.out.println("I can't fly");  
  14.     }  
  15.   
  16. }  

  1. package cn.partner4java.demo1.duck.impl;  
  2.   
  3. import cn.partner4java.demo1.duck.FlyBehavior;  
  4.   
  5. /** 
  6. * 会飞的鸭子 
  7. * @author partner4java 
  8. * 
  9. */  
  10. public class FlyWithWings implements FlyBehavior {  
  11.   
  12.     public void fly() {  
  13.         System.out.println("I'm flying!");  
  14.     }  
  15.   
  16. }  

  1. package cn.partner4java.demo1.duck.impl;  
  2.   
  3. import cn.partner4java.demo1.duck.QuackBehavior;  
  4.   
  5. public class Quack implements QuackBehavior {  
  6.   
  7.     public void quack() {  
  8.         System.out.println("Quack");  
  9.     }  
  10.   
  11. }  

  1. package cn.partner4java.demo1.duck.impl;  
  2.   
  3. import cn.partner4java.demo1.duck.QuackBehavior;  
  4.   
  5. public class Squeak implements QuackBehavior {  
  6.   
  7.     public void quack() {  
  8.         System.out.println("Squeak");  
  9.     }  
  10.   
  11. }  

  1. package cn.partner4java.demo1.duck.impl;  
  2.   
  3. import cn.partner4java.demo1.duck.Duck;  
  4.   
  5. public class ModelDuck extends Duck {  
  6.       
  7.     public ModelDuck(){  
  8.         flyBehavior = new FlyNoWay();  
  9.         quackBehavior = new Quack();  
  10.     }  
  11.       
  12.     @Override  
  13.     public void display() {  
  14.         System.out.println("I'm a model duck");  
  15.     }  
  16.   
  17. }  

  1. package cn.partner4java.demo1.duck.impl;  
  2.   
  3. import cn.partner4java.demo1.duck.QuackBehavior;  
  4.   
  5. public class MuteQuack implements QuackBehavior {  
  6.   
  7.     public void quack() {  
  8.         System.out.println("<Silence>");  
  9.     }  
  10.   
  11. }  


  1. package cn.partner4java.demo1.duck.impl;  
  2.   
  3. import cn.partner4java.demo1.duck.Duck;  
  4.   
  5. public class Test {  
  6.     public static void main(String[] args) {  
  7.         Duck duck = new ModelDuck();  
  8.         duck.performFly();  
  9.         duck.performQuack();  
  10.         System.out.println("---");  
  11.         duck.setQuackBehavior(new MuteQuack());  
  12.         duck.performFly();  
  13.         duck.performQuack();  
  14.           
  15. //      后台打印:  
  16. //      I can't fly  
  17. //      Quack  
  18. //      ---  
  19. //      I can't fly  
  20. //      <Silence>  
  21.     }  
  22.   
  23. }  

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

head first 设计模式:策略模式 的相关文章

  • 设置 SWT Shell 的默认字体

    有没有办法为整个 Shell 设置默认字体 以便任何新控件都将使用相同的字体 看来现在我必须为我创建的每个控件设置字体 这导致了太多的冗余 默认使用的字体由平台选择 请参阅中的其他信息 类字体 SWT 标准小部件工具包 http book
  • Java:高性能消息传递(单生产者/单消费者)

    我最初问这个问题here https stackoverflow com questions 3367192 java is while true loop in a thread bad whats the alternative 但我意
  • 对 Java 中 *any* 类的所有实例进行全排序

    我不确定以下代码是否能确保 Comparator 的 Javadoc 中给出的所有条件 class TotalOrder
  • 使用 Spring Data REST 处理自定义异常 (i18n)

    我正在使用 Spring Boot 1 5 4 和 Spring JPA Spring Data REST HATEOAS 我正在寻找一种最佳实践 Spring 方式 来自定义异常 Spring Data REST 正在管理添加 i18n
  • @OneToMany 与 @JoinTable 错误

    我试图理解 OneToMany with JoinTable 对于这样的场景 我正在使用 JPA 2 1 Hibernate 5 0 4 和 Oracle 11 XE 当我打电话时userDao save user 下面的代码 我有 jav
  • 如何识别 Java 中的不可变对象

    在我的代码中 我正在创建一个对象集合 这些对象将由各种线程以只有在对象不可变的情况下才安全的方式访问 当尝试将新对象插入到我的集合中时 我想测试它是否是不可变的 如果不是 我将抛出异常 我能做的一件事是检查一些众所周知的不可变类型 priv
  • 在 TestNG 中运行多个类

    我正在尝试自动化一个场景 其中我想登录一次应用程序 然后进行操作而无需再次重新登录 考虑一下 我有在特定类的 BeforeSuite 方法中登录应用程序的代码 public class TestNGClass1 public static
  • 要打乱的键值(整数、字符串)列表的最佳结构

    我需要在 Java 中实现一个结构 它是一个键值列表 类型为整数 字符串 并且我想对其进行洗牌 基本上 我想做类似的事情 public LinkedHashMap
  • 如何将自定义日志处理程序添加到 Google App Engine?

    我正在尝试向我的 java 应用程序添加自定义日志处理程序 我已经实现了一个扩展 java util Logging Handler 类的 InnerLogger 类 在我的logging properties中声明为处理程序 handle
  • 从 sbt 程序集运行 uber jar 会导致错误:无法找到或加载主类

    我有一个使用 sbt 程序集插件打包为 uber jar 的 Spark 作业 这build sbt指定一个可运行的 main 作为生成的 uber jar 的目标 mainClass in assembly Some com foo Ba
  • 打印 jasper 文件时执行报表 SQL 语句时出错

    我修改了一个旧项目 但无法确定这段代码有什么问题 使用下面的 jrxml它创造 jasper文件 当我打印 jasper 文件时 使用此代码JasperPrint jasperPrint JasperFillManager fillRepo
  • Java:使用 Java.util.concurrent 线程访问读取线程串行端口

    我正在尝试编写一个 Java 串行设备驱动程序并想使用 对我来说是新的 java util concurrent包裹 我有一种发送数据包然后等待 ACK 的方法 我打算有炭 接收在不同的线程中运行 如果接收线程收到 ACK 它应该使用发送数
  • 使用Java开发跨平台,不同平台字体缩放不同

    我正在为我的大学制作一些软件 需要一个 GUI 在它的第一个版本中 我让它使用系统外观 因此它看起来像 Linux Mac Windows 中的本机应用程序 我发现这很麻烦 因为我必须根据操作系统使所有 JLabel 具有不同的大小 无论分
  • 在Java中多次读取System.in会导致IOException?

    我正在尝试创建一个小命令行游戏来强化我在过去几个月中在 Java 中学到的一些东西 我正在尝试创建一个名为 readInput 的方法 它返回一个我可以一次又一次调用的字符串 第一次它工作正常 但第二次它会导致 IO Exception 如
  • 在服务器内部调用 Web 服务

    我有一个网络服务 getEmployee 当传递 id 时 它会获取单个员工的员工详细信息 同一服务器上的另一个 Web 服务 getEmployeeList 当传递一个部门时 它会获取整个员工列表 这将获取部门的 ID 然后调用 getE
  • 从命令行运行 Maven 插件的语法是什么。

    我看到这里已经有人问过这个问题 如何从命令行执行maven插件 https stackoverflow com questions 12930656 how to execute maven plugin from command line
  • Selenium - 等待网络流量

    我们将 Selenium 与 Java API 和一些 Javascript 用户扩展一起使用 我们在应用程序中使用了大量 AJAX 调用 我们的许多测试随机失败 因为有时 AJAX 调用完成得比其他时候慢 因此页面未完全加载 我们通过等待
  • Google Cloud Messaging - 立即收到或长时间延迟收到的消息

    我在大学最后一年的项目中使用谷歌云消息传递 一切正常 但我在使用 GCM 时遇到了一些麻烦 通常 消息要么几乎立即传递 要么有很大的延迟 我读过这篇文章 但我真的认为它不适用于这种情况 GCM 通常会在消息发送后立即传送消息 然而 这并不总
  • 编写自定义 Eclipse 调试器

    EDIT 一定有某种方法可以解决这个问题 而无需编写全新的调试器 我目前正在研究在现有 java 调试器之上构建的方法 如果有人对如何获取 Java 调试器已有的信息 有关堆栈帧 变量 原始数据等 有任何想法 那将非常有帮助 我想要做的是我
  • Integer.parseInt 引发的 NumberFormatException

    嘿 我在学校上编码课 但老师没有很好地解释 所以我们必须在网上查找我所做的信息 但我无法找到代码中的错误 你能帮我吗 char end s do System out println Tipo de boleto char boleto c

随机推荐

  • Qt 模型视图编程之增删行列

    背景 Qt 模型视图编程中模型定义了标准接口对数据进行访问 可根据需求继承对应的抽象模型类来实现自定义的数据模型 一个基本的数据模型至少要实现以下虚函数 rowCount 行数 返回要显示多少行 columnCount 列数 返回要显示多少
  • slf4j中的MDC

    一 slf4j中MDC是什么 slf4j除了trace debug info warn error这几个日志接口外 还可以配合MDC将数据写入日志 换句话说MDC也是用来记录日志的 但它的使用方式与使用日志接口不同 在使用日志接口时我们一般
  • 简易多元线性回归学习

    目录 多元线性回归 一 问题分析 二 数据预处理 excel 1 数据清洗 2 数据全数值化 三 使用EXcel回归 回归实现 回归分析 四 使用代码实现回归 Statsmodels 1 数据处理 2 绘制热力图探讨价格与其他之间的联系 3
  • ceph安装部署

    Ceph 简介 存储基础 单机存储设备 单机存储的问题 分布式存储的类型 分布式存储 软件定义的存储 SDS Ceph 架构 Ceph 核心组件 编辑 Pool中数据保存方式支持两种类型 OSD 存储后端 Ceph 数据的存储过程 Ceph
  • 灰度发布是什么?

    在如今的互联网时代 大厂都是采用灰度发布的策略进行应用线上部署的 如果身在小公司的测试同学想进入大厂 那么灰度发布就是大家必须要了解的知识点了 希望通过本文能够帮助大家快速的理解什么是灰度发布 并让大家了解研发 运维 测试 运营是如何在这一
  • pnpm与npm和yarn的区别

    作为一名前端程序员 对npm和yarn这两个包管理器一定不陌生 那么你听说过pnpm么 它到底是个什么东西 和npm还有yarn有什么区别 又有什么作用呢 本文就将解决以下这几个问题 pnpm是什么 有什么作用 pnpm有什么优势和特点 p
  • 国产中标麒麟系统-docker安装

    背景 中标麒麟的 华为国产机器 需要安装docker 但是在线安装老是失败 可能操作不对 离线安装可以的 不管怎么样 安装成功就是目的 系统架构是aarch64 如果你是其他系统架构 按照这个步骤离线安装是可以的 不过安装包需要换一下相应路
  • Spring 事务管理

    http www redsaga com spring ref 2 0 html transaction html transaction declarative 9 1 简介 Spring框架引人注目的重要因素之一是它全面的事务支持 Sp
  • 如何不让访问php文件路径,防止别人通过路径查看你的模板文件方法汇总nginx篇...

    为了防止别个盗取你辛苦的模板 做一个安全防护还是有必要的 之前的一篇已经介绍了apache下如何禁止的办法 这一篇将介绍nginx下的方法 通过nginx一般都是通过配置文件nginx conf配置来禁止用户访问的 1 禁止访问corefr
  • Excel大数据量单元格快速填充

    个人简介 一个从会计转行数据分析师的三旬老汉 擅长领域 数据分析 数据仓库 大数据 博客内容 平时会将自己工作中遇到的问题进行归纳总结 分享给各位小伙伴 意在帮助大家少加班 不掉发 让我们相互学习 一起进步 文章目录 前言 一 填充 一 编
  • C51教程 第三个51程序:数码管显示

    keil proteus 第三个51程序 让数码管循环显示0 9 这是一个AT89c51单片机教程 我们每次都会提供博文教程以及附带资料下载 单片机就是一个小型CPU 在电子领域应用广泛 电视 冰箱 洗衣机 空调等产品中都能见到他们的身影
  • 【C语言】让你不再害怕指针——C指针详解(经典,非常详细)

    目录 前言 复杂类型说明 一 细说指针 1 指针的类型 2 指针所指向的类型 3 指针的值 或者叫指针所指向的内存区或地址 4 指针本身所占据的内存区 二 指针的算术运算 三 运算符 和 四 指针表达式 五 数组和指针的关系 六 指针和结构
  • GPT专业应用:如何让GPT策划方案

    身为一名职场打工人 或多或少会面临需要写策划案的难题 不管是策划一场线下活动 还是策划业务发展的方向 甚至到生活中还需要策划婚礼 策划房屋装修 策划和朋友的聚会等等 那么如何快速积累经验 找准方向便成为了不可或缺的技能 在这里 我们将介绍如
  • python输出最长字符串_使用Python打印最长的字母子字符串,并打结...

    我将通过以下方式解决该问题 gt 让我们定义两个字符串 当前字母递增的字符串和当前最长的字符串 gt 两个字符串都以第一个字母初始化 这样我们就可以随时阅读他们的最后一封信 gt 然后遍历输入字符串s 从第二个字符开始 gt 如果当前字符c
  • 合并两个有序单链表(Java)

    思想 准备两个链表l1和l2 判断是否有链表为空 如果l1为空 则不用比较直接返回l2 如果l1为空 则直接返回l2 比较l1和l2节点 选出最小的那个节点 将该节点设为合并后的链表的head 头 节点 同时将指向该节点的l1或l2后移 方
  • 广告投放算法:受众行为分析与人群定向

    引言 物以类聚 人以群分 这句古语不仅揭示了物与人的自组织趋向 更隐含了 聚类 和 人群 之间的内在联系 例如在现代数字广告投放系统中 最为关键的 人群定向 功能正是通过 聚类 算法得以实现的 如果您厌倦了隔靴搔痒的空大宣传 不妨就随笔者一
  • 微信支付服务端开发总结

    原文链接 http blog csdn net baple article details 68059283 前言 最近应公司业务需求 把微信支付完成了 当然已经顺利上线 但是开发的过程是也是踩了很多坑 下面我就先说说开发流程 以及在开发中
  • Kotlin泛型的型变之路

    一 JAVA泛型的协变 简而言之 协变就是 如果A是B的子类 那么Generic a 就是Generic 实际上就是List a
  • SMT精密电阻对照表

    SMT 精密电阻对照表 代码 阻值 代码 阻值 代码 阻值 代码 阻值 01 100 27 187 53 348 79 649 02 102 28 191 54 357 80 665
  • head first 设计模式:策略模式

    策略模式 定义了算法族 分别封装起来 让他们之间可以互相替换 此模式让算法的变化独立于使用算法的客户 差不多应该是不固定模块的分离 当涉及 维护 时 为了 复用 reuse 目的而使用继承 结局并不完美 设计原则 找出应用中可能需要变化之外