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

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

相关文章

nginx -t、nginx -s stop 和 nginx -s reload 命令的详细解析(结合应用场景)

《nginx-t、nginx-sstop和nginx-sreload命令的详细解析(结合应用场景)》本文解析Nginx的-t、-sstop、-sreload命令,分别用于配置语法检... 以下是关于 nginx -t、nginx -s stop 和 nginx -s reload 命令的详细解析,结合实际应

MyBatis中$与#的区别解析

《MyBatis中$与#的区别解析》文章浏览阅读314次,点赞4次,收藏6次。MyBatis使用#{}作为参数占位符时,会创建预处理语句(PreparedStatement),并将参数值作为预处理语句... 目录一、介绍二、sql注入风险实例一、介绍#(井号):MyBATis使用#{}作为参数占位符时,会

PostgreSQL的扩展dict_int应用案例解析

《PostgreSQL的扩展dict_int应用案例解析》dict_int扩展为PostgreSQL提供了专业的整数文本处理能力,特别适合需要精确处理数字内容的搜索场景,本文给大家介绍PostgreS... 目录PostgreSQL的扩展dict_int一、扩展概述二、核心功能三、安装与启用四、字典配置方法

Java设计模式---迭代器模式(Iterator)解读

《Java设计模式---迭代器模式(Iterator)解读》:本文主要介绍Java设计模式---迭代器模式(Iterator),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录1、迭代器(Iterator)1.1、结构1.2、常用方法1.3、本质1、解耦集合与遍历逻辑2、统一

深度解析Java DTO(最新推荐)

《深度解析JavaDTO(最新推荐)》DTO(DataTransferObject)是一种用于在不同层(如Controller层、Service层)之间传输数据的对象设计模式,其核心目的是封装数据,... 目录一、什么是DTO?DTO的核心特点:二、为什么需要DTO?(对比Entity)三、实际应用场景解析

Java 线程安全与 volatile与单例模式问题及解决方案

《Java线程安全与volatile与单例模式问题及解决方案》文章主要讲解线程安全问题的五个成因(调度随机、变量修改、非原子操作、内存可见性、指令重排序)及解决方案,强调使用volatile关键字... 目录什么是线程安全线程安全问题的产生与解决方案线程的调度是随机的多个线程对同一个变量进行修改线程的修改操

深度解析Java项目中包和包之间的联系

《深度解析Java项目中包和包之间的联系》文章浏览阅读850次,点赞13次,收藏8次。本文详细介绍了Java分层架构中的几个关键包:DTO、Controller、Service和Mapper。_jav... 目录前言一、各大包1.DTO1.1、DTO的核心用途1.2. DTO与实体类(Entity)的区别1

Java中的雪花算法Snowflake解析与实践技巧

《Java中的雪花算法Snowflake解析与实践技巧》本文解析了雪花算法的原理、Java实现及生产实践,涵盖ID结构、位运算技巧、时钟回拨处理、WorkerId分配等关键点,并探讨了百度UidGen... 目录一、雪花算法核心原理1.1 算法起源1.2 ID结构详解1.3 核心特性二、Java实现解析2.

使用Python绘制3D堆叠条形图全解析

《使用Python绘制3D堆叠条形图全解析》在数据可视化的工具箱里,3D图表总能带来眼前一亮的效果,本文就来和大家聊聊如何使用Python实现绘制3D堆叠条形图,感兴趣的小伙伴可以了解下... 目录为什么选择 3D 堆叠条形图代码实现:从数据到 3D 世界的搭建核心代码逐行解析细节优化应用场景:3D 堆叠图

深度解析Python装饰器常见用法与进阶技巧

《深度解析Python装饰器常见用法与进阶技巧》Python装饰器(Decorator)是提升代码可读性与复用性的强大工具,本文将深入解析Python装饰器的原理,常见用法,进阶技巧与最佳实践,希望可... 目录装饰器的基本原理函数装饰器的常见用法带参数的装饰器类装饰器与方法装饰器装饰器的嵌套与组合进阶技巧