设计模式之美
王争
前Google工程师,《数据结构与算法之美》专栏作者
立即订阅
21264 人已学习
课程目录
已更新 65 讲 / 共 100 讲
0/6登录后,你可以任选6讲全文学习。
开篇词 (1讲)
开篇词 | 一对一的设计与编码集训,让你告别没有成长的烂代码!
免费
设计模式学习导读 (3讲)
01 | 为什么说每个程序员都要尽早地学习并掌握设计模式相关知识?
02 | 从哪些维度评判代码质量的好坏?如何具备写出高质量代码的能力?
03 | 面向对象、设计原则、设计模式、编程规范、重构,这五者有何关系?
设计原则与思想:面向对象 (11讲)
04 | 理论一:当谈论面向对象的时候,我们到底在谈论什么?
05 | 理论二:封装、抽象、继承、多态分别可以解决哪些编程问题?
06 | 理论三:面向对象相比面向过程有哪些优势?面向过程真的过时了吗?
07 | 理论四:哪些代码设计看似是面向对象,实际是面向过程的?
08 | 理论五:接口vs抽象类的区别?如何用普通的类模拟抽象类和接口?
09 | 理论六:为什么基于接口而非实现编程?有必要为每个类都定义接口吗?
10 | 理论七:为何说要多用组合少用继承?如何决定该用组合还是继承?
11 | 实战一(上):业务开发常用的基于贫血模型的MVC架构违背OOP吗?
12 | 实战一(下):如何利用基于充血模型的DDD开发一个虚拟钱包系统?
13 | 实战二(上):如何对接口鉴权这样一个功能开发做面向对象分析?
14 | 实战二(下):如何利用面向对象设计和编程开发接口鉴权功能?
设计原则与思想:设计原则 (12讲)
15 | 理论一:对于单一职责原则,如何判定某个类的职责是否够“单一”?
16 | 理论二:如何做到“对扩展开放、修改关闭”?扩展和修改各指什么?
17 | 理论三:里式替换(LSP)跟多态有何区别?哪些代码违背了LSP?
18 | 理论四:接口隔离原则有哪三种应用?原则中的“接口”该如何理解?
19 | 理论五:控制反转、依赖反转、依赖注入,这三者有何区别和联系?
20 | 理论六:我为何说KISS、YAGNI原则看似简单,却经常被用错?
21 | 理论七:重复的代码就一定违背DRY吗?如何提高代码的复用性?
22 | 理论八:如何用迪米特法则(LOD)实现“高内聚、松耦合”?
23 | 实战一(上):针对业务系统的开发,如何做需求分析和设计?
24 | 实战一(下):如何实现一个遵从设计原则的积分兑换系统?
25 | 实战二(上):针对非业务的通用框架开发,如何做需求分析和设计?
26 | 实战二(下):如何实现一个支持各种统计规则的性能计数器?
设计原则与思想:规范与重构 (11讲)
27 | 理论一:什么情况下要重构?到底重构什么?又该如何重构?
28 | 理论二:为了保证重构不出错,有哪些非常能落地的技术手段?
29 | 理论三:什么是代码的可测试性?如何写出可测试性好的代码?
30 | 理论四:如何通过封装、抽象、模块化、中间层等解耦代码?
31 | 理论五:让你最快速地改善代码质量的20条编程规范(上)
32 | 理论五:让你最快速地改善代码质量的20条编程规范(中)
33 | 理论五:让你最快速地改善代码质量的20条编程规范(下)
34 | 实战一(上):通过一段ID生成器代码,学习如何发现代码质量问题
35 | 实战一(下):手把手带你将ID生成器代码从“能用”重构为“好用”
36 | 实战二(上):程序出错该返回啥?NULL、异常、错误码、空对象?
37 | 实战二(下):重构ID生成器项目中各函数的异常处理代码
设计原则与思想:总结课 (3讲)
38 | 总结回顾面向对象、设计原则、编程规范、重构技巧等知识点
39 | 运用学过的设计原则和思想完善之前讲的性能计数器项目(上)
40 | 运用学过的设计原则和思想完善之前讲的性能计数器项目(下)
设计模式与范式:创建型 (7讲)
41 | 单例模式(上):为什么说支持懒加载的双重检测不比饿汉式更优?
42 | 单例模式(中):我为什么不推荐使用单例模式?又有何替代方案?
43 | 单例模式(下):如何设计实现一个集群环境下的分布式单例模式?
44 | 工厂模式(上):我为什么说没事不要随便用工厂模式创建对象?
45 | 工厂模式(下):如何设计实现一个Dependency Injection框架?
46 | 建造者模式:详解构造函数、set方法、建造者模式三种对象创建方式
47 | 原型模式:如何最快速地clone一个HashMap散列表?
设计模式与范式:结构型 (8讲)
48 | 代理模式:代理在RPC、缓存、监控等场景中的应用
49 | 桥接模式:如何实现支持不同类型和渠道的消息推送系统?
50 | 装饰器模式:通过剖析Java IO类库源码学习装饰器模式
51 | 适配器模式:代理、适配器、桥接、装饰,这四个模式有何区别?
52 | 门面模式:如何设计合理的接口粒度以兼顾接口的易用性和通用性?
53 | 组合模式:如何设计实现支持递归遍历的文件系统目录树结构?
54 | 享元模式(上):如何利用享元模式优化文本编辑器的内存占用?
55 | 享元模式(下):剖析享元模式在Java Integer、String中的应用
设计模式与范式:行为型 (6讲)
56 | 观察者模式(上):详解各种应用场景下观察者模式的不同实现方式
57 | 观察者模式(下):如何实现一个异步非阻塞的EventBus框架?
58 | 模板模式(上):剖析模板模式在JDK、Servlet、JUnit等中的应用
59 | 模板模式(下):模板模式与Callback回调函数有何区别和联系?
60 | 策略模式(上):如何避免冗长的if-else/switch分支判断代码?
61 | 策略模式(下):如何实现一个支持给不同大小文件排序的小程序?
不定期加餐 (3讲)
加餐一 | 用一篇文章带你了解专栏中用到的所有Java语法
加餐二 | 设计模式、重构、编程规范等相关书籍推荐
春节特别加餐 | 王争:如何学习《设计模式之美》专栏?
免费
设计模式之美
登录|注册

60 | 策略模式(上):如何避免冗长的if-else/switch分支判断代码?

王争 2020-03-20
上两节课中,我们学习了模板模式。模板模式主要起到代码复用和扩展的作用。除此之外,我们还讲到了回调,它跟模板模式的作用类似,但使用起来更加灵活。它们之间的主要区别在于代码实现,模板模式基于继承来实现,回调基于组合来实现。
今天,我们开始学习另外一种行为型模式,策略模式。在实际的项目开发中,这个模式也比较常用。最常见的应用场景是,利用它来避免冗长的 if-else 或 switch 分支判断。不过,它的作用还不止如此。它也可以像模板模式那样,提供框架的扩展点等等。
对于策略模式,我们分两节课来讲解。今天,我们讲解策略模式的原理和实现,以及如何用它来避免分支判断逻辑。下一节课,我会通过一个具体的例子,来详细讲解策略模式的应用场景以及真正的设计意图。
话不多说,让我们正式开始今天的学习吧!

策略模式的原理与实现

策略模式,英文全称是 Strategy Design Pattern。在 GoF 的《设计模式》一书中,它是这样定义的:
Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《设计模式之美》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(39)

  • 宁锟
    仍然可以用查表法,只不过存储的不再是实例,而是class,使用时获取对应的class,再通过反射创建实例
    2020-03-20
    2
    16
  • 下雨天
    策略模式和工厂模式区别:

    工厂模式
    1.目的是创建不同且相关的对象
    2.侧重于"创建对象"
    3.实现方式上可以通过父类或者接口
    4.一般创建对象应该是现实世界中某种事物的映射,有它自己的属性与方法!

    策略模式
    1.目的实现方便地替换不同的算法类
    2.侧重于算法(行为)实现
    3.实现主要通过接口
    4.创建对象对行为的抽象而非对对象的抽象,很可能没有属于自己的属性。
    2020-03-20
    9
  • Frank
    打卡 今日学习策略模式,收获如下:
    策略模式,理解有多种策略可供使用,怎么使用。文章中提到三部分:策略的定义,策略的创建,策略的使用。定义:需要定义策略接口和一组实现类,使用基于接口而非实现编程可灵活替换不同的类,各个实现类可独立变化。创建: 创建策略类时,为了封装创建细节,
    使用简单工厂方法。根据策略类状态特性(可变类与不可变类)来判断是使用可缓存的,还是每次都返回新的。使用:基于两种方式:运行时动态确定和编译时静态确定,前者使用灵活,外界可灵活介入,后者硬编码,存在一定维护成本。
    课堂讨论中的问题可通过工厂方法即将不同的折扣策略计算对象的创建在拆分出来形成一个个小工厂,在小工厂里创建折扣策略对象,然后再使用简单工厂模式里面的第二种方式缓存这些小工厂,使用的时候根据类型返回小工厂,进而通过小工厂拿到相应的折扣策略对象。
    2020-03-21
    1
  • 每天晒白牙
    我们的项目就使用了这种动态的策略模式,减少 if-else
    2020-03-20
    2
    1
  • 攻城拔寨
    策略模式通常跟工厂一起配合使用。
    策略侧重如何灵活选择替换,
    工厂侧重怎么创建实例
    2020-03-20
    1
  • test
    用查表法缓存clasa
    2020-03-20
    1
  • Michael
    王老师,若是决定具体策略类的条件不是一个简单的type,而是多个条件决定一个具体的策略,如何处理?比如A和B有四种组合的这种
    2020-03-20
    2
    1
  • Michael
    一般而言Java web开发中我们均使用spring框架,可以使用运行时自定义注解给具体的策略类打上注解,将具体的策略类放于spring 容器中,工厂中注入直接根据类型获取即可.不实用spring框架的话,也可以用Java的反射做到获取到具体的策略类
    2020-03-20
    1
  • 就像老师说的,替换麻烦的ifelse本质上靠的是查表法,也就是if 里的条件成立绑定对应的方法地址,所以其实感觉和策略模式本身没有半毛钱关系,只不过在策略模式这个上下文下,每个条件分支是可扩展的策略实现而不是差别很大的功能代码。
    2020-03-20
    1
  • hetiu
    课后题: 用工厂的工厂可以解决。不过,查表的方式,不见得就比switch/case优雅多少!
    2020-03-22
  • 韵呀
    查表法,value值存class,用反射创建。
    策略类也可以继承一个抽象类吧,不一定是接口。策略类的一些公共处理可以放在抽象类里
    2020-03-22
  • 大张伟
    可用Spring的applicationContext.getBeansOfType(Interface.class);
    2020-03-22
  • L🚲🐱
    策略模式可以有效的解决 if else 过多的问题, 用 map 存放 具体的策略, 运行时生成对应的策略
    2020-03-22
  • 相逢是缘
    一、定义(理解):
    定义一族算法类,将每个算法分别封装起来,让它们可以互相替换。策略模式可以使算法的变化独立于使用它们的客户端(这里的客户端代指使用算法的代码)。

    二、使用场景:
    需要根据情况使用不同的算法类。

    三、实现方式:
    1、策略类的定义比较简单,包含一个策略接口和一组实现这个接口的策略类。
    2、策略的创建由工厂类来完成,封装策略创建的细节。
    3、策略模式包含一组策略可选,客户端代码如何选择使用哪个策略,有两种确定方法:编译时静态确定和运行时动态确定。其中,“运行时动态确定”才是策略模式最典型的应用场景。

    四、工厂模式和策略模式的区别
    工厂模式
    1.目的是创建不同且相关的对象
    2.侧重于"创建对象"
    3.实现方式上可以通过父类或者接口

    策略模式
    1.目的实现方便地替换不同的算法类
    2.侧重于算法(行为)实现
    3.实现主要通过接口
    2020-03-22
  • Michael
    我觉得结合下Spring中的应用场景讲下,毕竟大家都是依赖Spring开发的
    2020-03-22
  • Geek_3b1096
    学习查表法
    2020-03-22
  • 朱晋君
    讲解清晰简洁,期待下一节
    2020-03-21
  • howdyli
    老师结合spring和应用场景讲解一下,这样更适用。
    2020-03-21
  • 小刀
    策略:侧重不同算法实现,通过接口实现,方便动态替换不同的算法实现
    2020-03-21
  • 孙自友
    用type枚举类有创建策略类方法
    2020-03-21
收起评论
39
返回
顶部