「设计模式」汉堡中的设计模式——策略模式(1)

具体如何实现,就是每个算法内部的事情了,别人管不了,相当于是每一个ConcentrateStrategy

从类图上看到,标准的策略模式还要有一个组件Context,他就类似是策略模式的客户端,要调用哪一个策略,跟Context沟通,不跟具体实现沟通,这样做的好处就是实现客户端(真正的调用方)与具体实现间的解耦,如下图所示

「设计模式」汉堡中的设计模式——策略模式

所以,根据设计,我们把代码给敲一下

  • 首先是顶层接口代码

  • 然后是各个具体算法的实现

  • Context代码

  • 客户端调用情况输出结果

如果我要新添加一种形式呢?

=============

麦当劳“壕无人性”地说,今天薯条免费赠送,那么针对这种情况,很明显现有的算法家族是不支持的,那么我们只需要再添加一种算法,叫做【FreePrice】,然后交给Client调用即可

「设计模式」汉堡中的设计模式——策略模式

我们完全不需要动其他已经写好的算法,这很符合OCP原则,并且算法的具体实现也被完美的隐藏在各个实现类中,实在是很nice

策略模式的优点

=======

其实刚刚也讲了,这里再总结一下

  • 算法的具体实现封装在各个实现类中,客户端不需要知道

  • 客户端可以根据场合随意切换到底要使用哪一种策略

  • 将客户端与具体实现通过Context解耦,即符合OCP原则,又可以让具体算法独立发展而不会影响其他类修改

策略模式的局限

=======

那么,可能有小伙伴就想提问了,策略模式这么牛逼,他就没有一点局限性吗?这里引用我在看《Head First 设计模式》中看到的一段话,他的意思是

设计模式的定义告诉我们,问题包含了一个目标和一组约束;光明的方向就是你的目标,黑暗的方向就是这些约束

光明与黑暗总是相伴而生,所以策略模式的约束是什么?不妨从我们实际调用的方向入手,思考一下

商户在实际设置新行为的时候,肯定是会有一个UI界面,会有下拉选择本次要推出的形式,针对不同的形式,所需要的参数也不尽相同,例如形式是优惠卷满减的时候,需要有满减阈值,满减多少,优惠券时效等等参数

那么发送到后端创建的时候,url请求也许是这样子的(简单给个例子):newActivity?type=1

其中type就是标识,我们具体选择的策略,比如

  • type=1代表是原价

  • type=2代表是打折

  • type=3代表是满减

然后回看一下刚刚写的代码,在Client端调用,简直就是太过于理想化了,真正调用的时候,不可能这么写的

「设计模式」汉堡中的设计模式——策略模式

实际上,对应处理的Controller(客户端)在接收到方法的时候,最基础时要这么来判断

//伪代码,暂不校验字段有效性问题

if (1 == type)

then xxxx

else if (2 == type)

then xxxx

else if (3 == type)

then xxxx

else if (4 == type)

then xxxx

你说这个,跟我了解策略模式的局限性到底有什么关系啊?其实仔细品一下,就会发现,尽管我们把各个算法的实现细节都给隐藏了,当时我们依然需要知道有多少种策略,换言之就是,我们在选择策略的时候不免要进行判断,这就是策略模式一个局限

第二个就是,每次都需要新建一个类单独做一个算法策略,如果有很多很多的算法策略,就会导致类结构非常的膨胀,此时,就不易于维护和管理

解决局限性问题

=======

针对客户端存在一大堆的if-else,我们使用简单工厂的形式配合把他们都封装起来

简单工厂+策略模式解决客户端大量if-else情况

=========================

原来的设计不变,把Context给替换成HandlerFactory,通过静态方法返回信息,这里为了更加贴合实际,定义了两个VO对象

「设计模式」汉堡中的设计模式——策略模式

「设计模式」汉堡中的设计模式——策略模式

简单工厂

「设计模式」汉堡中的设计模式——策略模式

最终客户端调用

「设计模式」汉堡中的设计模式——策略模式

使用postman进行测试,为了方便起见,参数就不改变了,就改变type,实际上是不同的type,参数也会不相同

  1. type为1,原价方式

  2. type为2,优惠券满减策略

  3. type为3,折扣策略

  4. type为4,买一送一策略

  5. type为5,免费送策略

通过简单的工厂+策略模式,我们把原本存在于客户端中的判断给挪到工厂里面,把所有的运行逻辑都隐藏起来了;每次有新的策略,只需要新建一个类,修改一下HandlerFactory中的selectStrategy方法即可

不过这也导致了HandlerFactory这个类违背了OCP原则,但是相对于一大段的if-else直接暴露再客户端,这种方法无疑是值得考虑的

「设计模式」汉堡中的设计模式——策略模式

枚举策略方式

======

或许在看完【简单工厂+策略模式】之后小伙伴会有所疑问,这不就是把客户端的判断逻辑给转移到工厂中而已,虽然对于客户端来说,会更加的清爽,可是似乎没有根本性的解决问题,工厂中把if-else换成了switch-case,新的策略该创建类还是要创建类,所以该膨胀还是得膨胀啊。。。

那没办法了,只能出绝招了,

使用枚举策略模式,相当于策略来说,枚举策略更像是他的改良升级版本,使用起来也更加的灵活,不需要创建大量的类来充当各个具体实现,也不需要满屏幕的if-else或者switch-case,看起来就相当的诱人

枚举大家都使用过,常用来定义一些常量信息,而枚举策略就是在枚举类里边加上抽象方法,让每个常量都实现这些方法

例如,我在枚举里边定义这两个方法

「设计模式」汉堡中的设计模式——策略模式

那么我的每一个枚举成员都必须实现这两个方法

「设计模式」汉堡中的设计模式——策略模式

给出完整的代码

「设计模式」汉堡中的设计模式——策略模式

客户端调用情况

「设计模式」汉堡中的设计模式——策略模式

可以发现,原本各个实现类都不需要了,只需要在枚举中定义成员,即可达成原来的效果,而且在匹配对应的策略时,直接使用循环的方式,看起来非常的清爽

如果要添加新的策略,直接在枚举里边添加成员,实现对应的方法即可,而且将所有的策略统一管理起来,方便维护

唯一的缺点,可能就是策略越来越多的时候,这个枚举类也会越来越长,但是通过成员来管理,注释写好,也不会显示很混乱

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
hKMszlL-1715744028578)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值