Head First 设计模式 - 01. 策略 (Strategy) 模式

简介: Head First 设计模式 - 01. 策略 (Strategy) 模式
  • 当涉及到“维护”时,为了“复用”目的而使用继承,结局并不完美 P4
    • 对父类代码进行修改时,影响层面可能会很大

思考题

利用继承来提供 Duck 的行为,这会导致下列哪些缺点?(多选) P5

  • [ ] A. 代码在多个子类中重复
    • 使用继承就是为了复用代码
    • 【答案有此选项】从另一方面考虑,也有这个缺点,比如:多个子类都存在相同的实现,但又与父类的实现不同
  • [x] B. 运行时的行为不容易改变
    • 编译完成后,各种行为已经确定,无法再继续修改(第一次看没有选择,看完策略模式后又觉得有这个缺点)
  • [ ] C. 我们不能让鸭子跳舞
    • 在父类中写 dance() 的方法即可
  • [x] D. 很难知道所有鸭子的全部行为
    • 子类可以覆盖父类的方法,所以不知道子类的具体行为
  • [ ] E. 鸭子不能同时又飞又叫
    • 在父类中写 flyAndQuack() 即可
  • [x] F. 改变会牵一发而动全身,造成其他鸭子不想要的改变
    • 在父类 Duck 中增加 fly() 方法,就会使得所有的子类鸭子都会飞,包括不会飞的橡皮鸭

使用接口方式的优缺点 P6

优点
  • 可以避免继承时的出现有不应具有的的行为而大量覆盖
  • 在 Java8 中可以用默认方法实现和继承效果一样的代码复用
    缺点
  • 某一行为在子类中都具有,却有不同实现时,仍然有代码重复的问题
  • 在获取到父类时,必须得先用 instanceof 判断是否实现某接口,才能转换类型使用相关方法

思考题

驱动改变的因素很多。找出你的应用中需要改变代码的原因,一一列出来 P8

  • 我们的顾客或用户需要别的东西,或者想要新功能
  • 我的公司决定采用别的数据产品,又从另一家厂商买了数据,这造成数据格式不兼容
  • 重构
  • 性能优化
  • 修复BUG、安全问题

设计原则

取出并封装变化的部分,让其他部分不会受到影响 P9

  • 减少改变代码带来的影响
  • 便于修改和扩充,更具有弹性

设计原则

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

  • 可以在运行时动态改变实现
“针对接口编程”即“针对超类型 (supertype) 编程” P12
  • 接口既指一种“概念”,也指 Java 的 interface

设计原则

多用组合,少用继承 P23

  • 组合具有弹性,可以动态改变实现

策略模式

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

  • 其实没学的时候也经常凭借经验不知不觉中使用到了策略模式,比如:不同字段的校验逻辑、不同推荐策略、不同车型匹配逻辑等等。
  • 策略模式在 Java 源码中可以说随处可见,比如 ThreadPoolExecutor 中的 RejectedExecutionHandler 就是策略,用来进行拒绝新任务。可以在初始化线程池的时候可以设置相应的四种拒绝策略中的一种以满足不同的需要

    private volatile RejectedExecutionHandler handler;
    
    // RejectedExecutionHandler 接口定义
    public interface RejectedExecutionHandler {
        void rejectedExecution(Runnable r, ThreadPoolExecutor executor);
    }
  • 刚开始看到策略模式和观察者模式的时候,感觉两者差不多(或者说是观察者模式自带策略模式)。后来有仔细思考了一下, 两者的区别主要还是在使用场景上。策略模式主要是调用策略的一方想通过这个策略完成自己所需要的功能,一般每次只有一种策略;观察者模式主要是主题想通知观察者使观察者完成自己的功能,可以存在多个不同的观察者

良好的OO设计具备的特性 P32

  • 可复用
  • 可扩充
  • 可维护

所思所想

  • 经验和实战的作用还是挺大的,一直在潜移默化地影响代码风格和思考方式
  • 系统地学习相关知识,可以使自己思考更全面,从思考架构的层次提高到模式层面
  • 平时写代码时也总会想到哪些地方需要变化,并进行一定的处理;这是个好习惯,要继续坚持,但也要保证尽快开始第一步(或者边实现边设计),防止设计很久,却在实现时发现很多地方不适用的情况发生
  • 很多时候从不同方面考虑问题时,得到的答案并不一样,要有辩证思维

    本文首发于公众号:满赋诸机(点击查看原文) 开源在 GitHub :reading-notes/head-first-design-patterns

相关文章
|
1月前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
|
3月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。
|
1月前
|
设计模式 开发者 Python
Python编程中的设计模式:工厂方法模式###
本文深入浅出地探讨了Python编程中的一种重要设计模式——工厂方法模式。通过具体案例和代码示例,我们将了解工厂方法模式的定义、应用场景、实现步骤以及其优势与潜在缺点。无论你是Python新手还是有经验的开发者,都能从本文中获得关于如何在实际项目中有效应用工厂方法模式的启发。 ###
|
1月前
|
设计模式 安全 Java
Kotlin - 改良设计模式 - 构建者模式
Kotlin - 改良设计模式 - 构建者模式
|
1月前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
45 1
|
2月前
|
设计模式 Java Kotlin
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
本教程详细讲解Kotlin语法,适合希望深入了解Kotlin的开发者。对于快速学习Kotlin语法,推荐查看“简洁”系列教程。本文重点介绍了构建者模式在Kotlin中的应用与改良,包括如何使用具名可选参数简化复杂对象的创建过程,以及如何在初始化代码块中对参数进行约束和校验。
32 3
|
2月前
|
设计模式 监控 算法
Java设计模式梳理:行为型模式(策略,观察者等)
本文详细介绍了Java设计模式中的行为型模式,包括策略模式、观察者模式、责任链模式、模板方法模式和状态模式。通过具体示例代码,深入浅出地讲解了每种模式的应用场景与实现方式。例如,策略模式通过定义一系列算法让客户端在运行时选择所需算法;观察者模式则让多个观察者对象同时监听某一个主题对象,实现松耦合的消息传递机制。此外,还探讨了这些模式与实际开发中的联系,帮助读者更好地理解和应用设计模式,提升代码质量。
Java设计模式梳理:行为型模式(策略,观察者等)
|
2月前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
43 0
|
3月前
|
设计模式 算法 安全
设计模式——模板模式
模板方法模式、钩子方法、Spring源码AbstractApplicationContext类用到的模板方法
设计模式——模板模式
|
3月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:如何提高代码的可维护性与扩展性在软件开发领域,PHP 是一种广泛使用的服务器端脚本语言。随着项目规模的扩大和复杂性的增加,保持代码的可维护性和可扩展性变得越来越重要。本文将探讨 PHP 中的设计模式,并通过实例展示如何应用这些模式来提高代码质量。
设计模式是经过验证的解决软件设计问题的方法。它们不是具体的代码,而是一种编码和设计经验的总结。在PHP开发中,合理地使用设计模式可以显著提高代码的可维护性、复用性和扩展性。本文将介绍几种常见的设计模式,包括单例模式、工厂模式和观察者模式,并通过具体的例子展示如何在PHP项目中应用这些模式。