据说是程序员工作中用到的最多的模式:策略模式解析

2024-03-19 06:18

本文主要是介绍据说是程序员工作中用到的最多的模式:策略模式解析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这是从零学习设计模式的第一篇文章,也算是入门篇吧。

大家都知道设计模式很重要,掌握设计模式是一个高级开发乃至架构师都必须要具备的技能。 但是不知道有没有这样的感觉,每次看设计模式的概念都差不多能看懂,但是就是不会用,而且不能够识别一些优秀的代码具体是运用了什么设计模式? 最终的结果就是,慢慢的忘记,脑海中的设计模式只是一个很大很虚的概念。

我目前就属于这种状态,为了能够提高自己的编码设计能力,在工作中设计出有弹性,好维护,能更好的应付业务变化的代码,准备认真学习一边设计模式。

其实大学期间就断断续续看过《Head First 设计模式》,但是当时印象也不深刻,工作后也不太会用。 到现在工作快四年了,再次看这本书,感觉真的不一样,也是因为工作这几年有了实战经验,慢慢知道了平时开发中的痛点,最后优化形成的解决方案,其实有很多就是用到了设计模式的思想。

目标

作为 Java 程序员,我们已经进入到对象村,OO思想和设计是已经深入人心的潜规则。 但是 良好的 OO 设计,并不是那么简单的,要结合前人大量的实践经验总结,不断的艰苦联系才能成功。 而这些前人的经验就是已经整理好的设计模式。

使用设计模式最好的方式是:“把模式装进脑子里,然后在你的设计和已有的应用中,寻找何处可以使用它们”。平时我们做的最多的是代码复用,而学习设计模式其实是经验复用。

一定要多回顾、多思考、多实践,这样才能深入理解和使用好设计模式。

入门:鸭子系统的设计

中级程序员的设计实现

我们来看一个简单的例子,鸭子系统的设计严谨,去理解设计模式带来的影响。

有一款模拟鸭子游戏,游戏中有很多种鸭子,会游泳,会呱呱叫,这时候利用 标准的 OO 技术,设计如下:

继承来实现

游泳和叫所有鸭子都会,所以为了代码复用,在基类中实现,外观由于各不相同是抽象方法,下沉到子类去实现,ok,符合 OO 思想,到此就结束了? 那只能说你太年轻。。

需求变更: 主管确定要求游戏中有会飞的鸭子,这时候你评估需求时,信誓旦旦的说,我们三天搞定。。。嗯。。加下班,明天就可以上线。

毕竟作为一名 OO 程序员,这没什么困难的,你直接在鸭子的基类中添加一个 fly() 方法,然后就被子类继承了, OO 大显神功。

但是,这个时候问题出现了,领导在测试环境做体验的时候,发现以前的 "僵尸鸭子" 居然也在天上飞来飞去,这下炸了,对代码局部的修改,居然影响到了全局,让一些没有生命力的鸭子也会飞上天了。

这个时候,你可能想到继承,可以在子类中覆盖父类的实现,将 “僵尸鸭子”的 fly() 非法覆盖掉,改为不会飞 。。。

这样虽然也可以,但是你要想到,如果后续又加入了 “诱饵鸭” 即不会飞也不会叫,这难道也要去其实现中重写对应的方法??

要知道作程序员,你一定要牢记一个不变的真理,那就是 CHANGE! 不管一开始设计的多么好,一段时间后,总是需要成长与改变。

到这里你也发现了,继承中的缺点是:

  1. 代码在多个子类中重复;
  2. 运行时的行为不容易改变,必须通过硬编码;
  3. 很难知道所有鸭子的全部行为,不同的子类实现不一样;
  4. 改一处就会动全身,造成子类鸭子不想要的改变;
把行为设计成接口

你可能会想到,将飞行行为和呱呱叫设计为对应的接口,有对应需要的鸭子直接去实现就好了,虽然这个方法是可以解决问题,但是你要想到,后续鸭子越来越多,每个都需要去实现飞行和呱呱叫接口,这样得要写多少重复的代码,无疑又掉入了另一个坑中。

模式大师来设计

找出应用中可能需要变化的,把它们独立出来进行封装

如果找到代码中可能需要变化的呢?

  1. 每次新需求来了,都会使某方面的代码发生变化,那么就可以确定,这部分代码需要被抽出来,和其他稳定的代码区分;
  2. 凭借自己对需求的理解,在一开始设计时将未来需求改变的代码抽出来封装;

这其实就是很多设计模式背后的精神所在,也是一种设计原则:“将会变化的部分取出来并封装起来,以便以后可以轻易地改动或扩充此部分,而不影响不需要变化的其他部分”。

所以,结合鸭子系统的需求,我们可以发现,鸭子的行为是经常变化的,因为有的会飞有的不会飞,有的会叫有的不会叫,所以需要抽出来进行封装。而其他部分还是比较正常的,所以依旧放到 Duck 基类中。

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

上面我们已经知道了要将鸭子的 飞行和呱呱叫行为 抽出来封装,那么该如何实现呢?

我们的设计目标就是一切都有弹性,避免出现 中级开发工程师设计的系统,由于没有弹性所以才去请了模式大师出手。

大师将鸭子的行为设计成接口,如 FlyBehavior、QuackBehavior,这样行为就可以动态的扩展,我们可以在鸭子类中包含行为的方法,然后在 “运行时” 动态的 “改变” 飞行和呱呱叫行为。

也就是在,大师的设计中,鸭子的子类将使用接口(FlyBehavior 和 QuackBehavior)所表示的行为,所以实际的实现不会被绑死在鸭子的子类中。

而且我们也可以新增一些行为,不会影响到既有的飞行和呱呱叫行为,也不会影响 “使用”到已有行为的鸭子类,

多用组合,少用继承

相信这个概念你不是第一次听到了,组合优于继承,因为使用组合建立的系统拥有很大的弹性,可以“在运行时动态的改变行为”,因为结合上面的针对接口编程,只要组合的行为符合接口定义标准即可。

下面我们一起来看下,最终的系统结构:

认真去看下设计图,代码应该很好实现了,我就不写了。

设计模式:策略模式

上面大师的设计,就引出了我们今天要学习的设计模式:策略模式。不要怀疑,正是使用了策略模式改写了我们的鸭子系统。

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

思考与提升

  1. 我们如何使用设计模式?

我们开发中都是使用设计好的库和框架,这个没有问题,我们享受着别人代码的便利性,但是如何组装到我们的应用系统中,使我们的应用系统变得 易了解、容易维护、具有弹性,这个就需要设计模式出马了。但是设计模式不会直接进入你的代码中,你要做的就是先让设计模式进入你的大脑中,这样在开始新设计又或者当旧代码一团乱麻时,你就可以运用它们。

  1. 一开始想不到可用的设计模式?

这个是我们初学者必然遇到的问题,别慌,先牢记一些面向对象的原则,因为它们适用于所有模式,当我们踩过坑,不断思考这些原则最终的方案往往就是设计模式了。

OO基础:

  1. 抽象
  2. 封装
  3. 多态
  4. 继承

本文设计的OO原则(后续还有更多): 封装变化 多用组合,少用继承 针对接口编程,不针对实现编程

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

更多精彩文章,可以关注我哦!
扫码关注

这篇关于据说是程序员工作中用到的最多的模式:策略模式解析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/825061

相关文章

找完工作该补充的东西

首先: 锻炼身体,包括乒乓球,羽毛球,都必须练习,学习,锻炼身体等是一个很重要的与人交际沟通的方式; 打牌,娱乐:会玩是一个人很重要的交际沟通的法宝; 摄影:这个是一个兴趣爱好,也是提高自己的审美,生活品质,当然也是与人沟通的重要途径; 做饭:这个的话就是对自己,对朋友非常有益的一件事情;

解析 XML 和 INI

XML 1.TinyXML库 TinyXML是一个C++的XML解析库  使用介绍: https://www.cnblogs.com/mythou/archive/2011/11/27/2265169.html    使用的时候,只要把 tinyxml.h、tinystr.h、tinystr.cpp、tinyxml.cpp、tinyxmlerror.cpp、tinyxmlparser.

如何开启和关闭3GB模式

https://jingyan.baidu.com/article/4d58d5414dfc2f9dd4e9c082.html

十四、观察者模式与访问者模式详解

21.观察者模式 21.1.课程目标 1、 掌握观察者模式和访问者模式的应用场景。 2、 掌握观察者模式在具体业务场景中的应用。 3、 了解访问者模式的双分派。 4、 观察者模式和访问者模式的优、缺点。 21.2.内容定位 1、 有 Swing开发经验的人群更容易理解观察者模式。 2、 访问者模式被称为最复杂的设计模式。 21.3.观察者模式 观 察 者 模 式 ( Obser

工作流Activiti初体验—流程撤回【二】

已经玩工作流了,打算还是研究一下撤回的功能。但是流程图里面并不带撤回的组件,所以需要自己动态改造一下,还是延续上一个流程继续试验撤回功能。《工作流Activiti初体验【一】》 完整流程图 我们研究一下分发任务撤回到发起任务,其他环节的撤回类似 撤回的原理大概如下: 将分发任务后面的方向清空,把发起任务拼接到原来的判断网关,然后结束分发任务,这样流程就到发起任务了 此时的流程如上图,

工作流Activiti初体验【一】

在这里记录一下我的Activiti历程:(以下示例不涉及真实业务,所有逻辑均建立在学习的基础上) bpmn图 发起任务我设置了一个权限组user1,只要是这个权限的用户都可以发起任务 分发任务我设置了一个用户组,用户组中每个用户都可以处理这步流程,只要有一个人处理这步任务,分发的流程就算结束了 分发任务这一环节还有个判断,允许任务下发和不允许任务下发 任务分发完成则来到子流程,每个被分

【新闻】AI程序员要来了吗?阿里云官宣

内容提要 6 月 21 日,在阿里云上海 AI 峰会上,阿里云宣布推出首个AI 程序员。 据介绍,这个AI程序员具备架构师、开发工程师、测试工程师等多种岗位的技能,能一站式自主完成任务分解、代码编写、测试、问题修复、代码提交整个过程,最快分钟级即可完成应用开发,大幅提升研发效率。 近段时间以来,有关AI的实践应用突破不断,全球开发者加速研发步伐。有业内人士坦言,随着大模型性能逐渐提升,AI应

tf.split()函数解析

API原型(TensorFlow 1.8.0): tf.split(     value,     num_or_size_splits,     axis=0,     num=None,     name='split' ) 这个函数是用来切割张量的。输入切割的张量和参数,返回切割的结果。  value传入的就是需要切割的张量。  这个函数有两种切割的方式: 以三个维度的张量为例,比如说一

服务器雪崩的应对策略之----SQL优化

SQL语句的优化是数据库性能优化的重要方面,特别是在处理大规模数据或高频访问时。作为一个C++程序员,理解SQL优化不仅有助于编写高效的数据库操作代码,还能增强对系统性能瓶颈的整体把握。以下是详细的SQL语句优化技巧和策略: SQL优化 1. 选择合适的数据类型2. 使用索引3. 优化查询4. 范式化和反范式化5. 查询重写6. 使用缓存7. 优化数据库设计8. 分析和监控9. 调整配置1、