| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> Java知识库 -> 人人都会设计模式:策略模式 -> 正文阅读 |
|
[Java知识库]人人都会设计模式:策略模式 |
你好,我是看山。
定义策略模式,英文全称是 Strategy Design Pattern。在 GoF 的《设计模式》一书中,它是这样定义的:
翻译成中文就是:定义一族算法类,将每个算法分别封装起来,让它们可以互相替换。策略模式可以使算法的变化独立于使用它们的客户端。 这里所说的客户端代指使用算法的代码。 根据使用场景分类,策略模式是一种行为型模式,用于运行时控制类的行为或算法。 使用上的直观感受是,策略模式可以减少了 if-else/switch 分支代码。那减少分支代码有什么好处呢?
有编程经验的都知道,很多 bug 都是从分支逻辑产生的。我刚开始工作时晚上 12 点开始抓虫,一直抓到凌晨 2 点多,最后发现是有一个 if-else 分支中,在某个 if 前面少写了一个 else。下面是示例,实际代码比这个复杂很多:
结果写成了:
代码编译不会错,但是在执行时,某些 case 会不符合预期。 问题我们来看看策略模式出现的场景。 以电商系统的支付功能为例,最早的时候,我们可能为了更快上线,选择一个较多人使用的支付方式,比如微信支付(也有可能是支付宝支付,根据售卖场景不同区分)。这个时候,我们只需要判断用户是从 PC 页面进入还是 H5 进入即可。 后来,业务发展比较好,涉及人群更多了,于是需要对接支付宝支付。支付宝支付也分为了多种的支付场景,对接接口变多了,但是也在可控范围内。 再后来,我们需要对接银联支付、对接各银行接口,等等,支付接口变得越来越臃肿。于是,每对接一种支付方式,支付相关接口就会增加一倍。此时,这坨臃肿的代码,无论是修复简单的 bug,还是微调传输参数,都会影响整个支付逻辑,从而增加了在已有正常运行代码中引入错误的风险。 如果是多人协作开发,我们还会陷入代码合并时应付各种冲突的情况。终于,在某一时刻,我们看着这一坨代码,已经无从下手维护了。 解决方案首先,我们来分析一下上面的场景,不变的是系统内部的支付业务逻辑,变化的是支付方式。 支付方式的可变性在于,可能会与多种支付方式对接,对接参数、协议、地址等都会不同。根据设计模式的整体思想,我们将变化的单独出去,将不变的稳定下来。 这种处理方式就是策略模式建议的:找出负责用许多不同方式完成特定任务的类,然后将其中的算法抽取到一族被称为策略的独立类中。 调用这些策略类的是调用上下文,它持有对所有策略类的引用。上下文不执行任务,它是任务的指挥者,将工作委派给已连接的策略对象。关系如下: 很多教程到这里就结束了,如果你能够看到这里,而且还用心看了,你就会发现一丝丝的不一样。 根据迪米特法则(LOD,Law of Demeter),上下文不需要知道具体策略类的功能,只需要通过特定的接口,用于触发选中策略即可。也就是说,完整的策略模式,应该有具体的策略判断是否由该策略执行,上下文只需要知道有哪些策略就行了。这样改动之后,上下文还能够与工厂模式结合。如果策略是无状态策略,还可以在上下文中引入单例模式。 适用与不适用根据上面的定义,策略模式是围绕可以互换的算法来创建业务的。简单的说就是,分支逻辑隔离。
设计模式只是解决问题的优雅实现,并不一定适用所有情况,比如下面这几种,就可以不用非得实现策略模式:
示例代码还是以支付为例,因为都是演示,一切从简。我曾经主导过支付中台,如果想要具体实现,可以具体聊一下。 首先定义支付策略接口:
然后是微信支付和支付宝支付分别实现支付策略接口:
我们再来看看持有策略算法的上下文:
可以看到,上下文只需要知道策略算法的存在,至于算法是否符合要求,由算法自己判断。 调用就比较简单了:
文末总结策略模式可能用来减少分支逻辑,将不同的算法分离开来。如果配合工厂模式、单例模式,可以更加灵活的使用。如果是在 Spring 当中,借助自动注入,上下文甚至可以不知道具体策略实现。 最近刚看到一句话,“日拱一卒,功不唐捐”。坚持下去,每天学点新东西,给生活加点色彩。 推荐阅读你好,我是看山。游于码界,戏享人生。如果文章对您有帮助,请点赞、收藏、关注。我还整理了一些精品学习资料,关注公众号「看山的小屋」,回复“资料”即可获得。 个人主页:https://www.howardliu.cn |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 1:50:08- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |