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

  • 搞打折活动时,汉堡只需要5块大洋,通过指定链接,把汉堡加到购物车,创建订单,支付,等待出餐

  • 搞买一送一活动时,把汉堡添加到购物车,创建订单,支付,等待出餐

  • 搞满减活动时,把汉堡和中薯、那么大鸡排添加到购物车,凑足满减金额,创建订单,使用优惠券,支付出餐

通过画图的形式展示一下上述的逻辑

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

上面是完整的步骤,简化一下,我们只关注产生价值的部分,也就是客户支付了多少钱,取到了哪些食物

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

进一步说就是,商户可以随意切换形式,比如昨天有5元的板烧,今天点进去看发现没有了,但是多出来了其他的优惠,例如【麦乐鸡20粒】优惠券,后天进去发现优惠券都没了,只能原价购买等情况;但是无论形式是这样的,最终产出时的步骤都是一致的,例如这里就是支付和取餐

绕了这么久,其实就是要引出今天的主角————策略模式

策略模式

====

标准定义以及类图

定义一组算法,并封装每个算法,让它们彼此可以交换使用。策略模式让这些算法在客户端中使用起来更加独立

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

如果以上述例子来看,所有形式都是一种特定的算法

  • 原价购买是一种算法

  • 打折也是一种算法

  • 优惠券满减也是算法

  • 买一送一也是算法

算法具体的如何实现的,客户端不管,客户端只知道,我可以任意切换形式,并且达成想要的效果

就好比顾客知道有这个活动,但不用知道这个活动的其他细节,我只需要按照步骤操作即可有优惠

尝试编码

====

既然上述几种情况最终都需要支付和取餐,那么我们直接就定义一个顶层接口管理这些算法(相当于是AbstractStrategy),接口中有两个方法

  • 一个是返回实际需要付多少钱

  • 一个是返回实际取到的食物列表

具体如何实现,就是每个算法内部的事情了,别人管不了,相当于是每一个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,参数也会不相同

最后

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

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

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

img

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

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

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

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

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值