品牌 资讯 搭配 材料 时尚 热点 行业 首饰 玉石 行情

每日热议!实际业务中使用策略模式对代码进行重构

2023-05-20 15:25:02 来源:博客园
一.业务描述

最近在负责公司一个语音的微服务模块优化,这个模块主要的业务是:1.天猫精灵、小度、若琪、小京鱼、小爱同学、思必驰这些第三方音响对我们的用户进行oauth2/JWT授权;2.这些第三方音响服务调用我们的设备发现接口对公司的设备信息在第三方平台进行一个存储;3.第三方平台对用户发出的语音进行解析,然后识别出需要控制的设备再调用我们的设备控制接口对公司的设备进行控制;

二.需要优化的点

上述发现、控制接口分别写了五个API,并且在Controller层有着大量的业务校验,然后再在Controller层调用Service层的设备发现、控制方法;这些业务校验的逻辑一模一样;

字有点不好看,兄dei们献丑了,嘿嘿


(相关资料图)

三.优化(为方便演示这个举三个语音平台的例子)1.对不同平台的业务实现代码进行重构(图中的②)① 将之前的三个语音接口提取为同一个策略接口命名为:(VoiceStrategyService)
public interface VoiceStrategyService {    /**     * @description:  语音控制API     * @param: [jsonObject]     * @return: com.alibaba.fastjson.JSONObject     * @author: zhouhong     * @date: 2023/5/18 9:34     */    JSONObject operateApi(@RequestBody JSONObject jsonObject);}
② 其他几个实现类实现 (VoiceStrategyService) 这一个接口

其他几个语音实现类实现上面的那个策略接口,每个策略实现类对应一个业务场景,实现具体的方法逻辑。

@Service@Log4j2public class AliGenieServiceImpl implements VoiceStrategyService {    @Override    public JSONObject operateApi(JSONObject jsonObject) {        log.info("天猫精灵-设备发现/控制成功!");        return null;    }}
@Service@Log4j2public class DuerOSServiceImpl implements VoiceStrategyService {    @Override    public JSONObject operateApi(JSONObject jsonObject) {        log.info("小度-设备发现/控制成功!");        return null;    }}
@Service@Log4j2public class RokidServiceImpl implements VoiceStrategyService {    @Override    public JSONObject operateApi(JSONObject jsonObject) {        log.info("若琪-设备发现/控制成功!");        return null;    }}
@Service@Log4j2public class RokidServiceImpl implements VoiceStrategyService {    @Override    public JSONObject operateApi(JSONObject jsonObject) {        log.info("若琪-设备发现/控制成功!");        return null;    }}
③接下来,定义一个上下文类(VoiceStrategyContext),该类持有一个策略对象,并提供一个方法用于设置策略对象
/** * @description: 语音策略上下文 * @author: zhouhong * @date: 2023/5/20 14:27 * @version: 1.0 */public class VoiceStrategyContext {    @Resource    private VoiceStrategyService voiceStrategyService;    private void setVoiceStrategy(VoiceStrategyService voiceStrategyService) {        this.voiceStrategyService = voiceStrategyService;    }    private JSONObject executeStrategy(JSONObject jsonObject) {        if (voiceStrategyService != null) {            return voiceStrategyService.operateApi(jsonObject);        }        return null;    }    /**      * @description: 根据传过来的KEY值选择具体的策略      * @return: com.alibaba.fastjson.JSONObject      * @author: zhouhong      * @date: 2023/5/20 15:03      */    public JSONObject executeStrategyByKey(String key, JSONObject jsonObject) {        switch (key) {            case "aliGenie" : {                this.setVoiceStrategy(new AliGenieServiceImpl());                return this.executeStrategy(jsonObject);            }            case "duerOS" : {                this.setVoiceStrategy(new DuerOSServiceImpl());                return this.executeStrategy(jsonObject);            }            case "rokid" : {                this.setVoiceStrategy(new RokidServiceImpl());                return this.executeStrategy(jsonObject);            }            default: {                return null;            }        }    }}

这个如果在下一层调用时知道自己需要调用哪个策略,那么executeStrategyByKey() 方法可以直接忽略,具体调用如下所示:

/** * @description: 测试类 * @author: zhouhong * @date: 2023/5/20 15:06 * @version: 1.0 */public class TextMain {    public static void main(String[] args) {        VoiceStrategyContext voiceStrategyContext = new VoiceStrategyContext();        JSONObject jsonObject = new JSONObject();        // 天猫精灵        voiceStrategyContext.setVoiceStrategy(new AliGenieServiceImpl());        voiceStrategyContext.executeStrategy(jsonObject);        // 小度        voiceStrategyContext.setVoiceStrategy(new DuerOSServiceImpl());        voiceStrategyContext.executeStrategy(jsonObject);        // 若琪        voiceStrategyContext.setVoiceStrategy(new RokidServiceImpl());        voiceStrategyContext.executeStrategy(jsonObject);    }}

结果:

15:12:38.474 [main] INFO com.zhouhong.designpattern.strategy.service.impl.AliGenieServiceImpl - 天猫精灵-设备发现/控制成功!15:12:38.477 [main] INFO com.zhouhong.designpattern.strategy.service.impl.DuerOSServiceImpl - 小度-设备发现/控制成功!15:12:38.477 [main] INFO com.zhouhong.designpattern.strategy.service.impl.RokidServiceImpl - 若琪-设备发现/控制成功!

2.对开始那张图的 ① 进行代码提取

这个比较简单,直接选中需要提取的代码块 Windows系统中 按住Ctrl 和 Alt 再加 M 键,就可以快速的将需要提取的代码从方法中抽离出来,然后新建一个Service层接口对其进行实现即可,主要示例代码如下:

/** * @description: 语音控制公共方法抽取 * @author: zhouhong * @date: 2023/5/17 10:58 * @version: 1.0 */public interface VoiceCommonApiService {    /**     * @description:  语音控制公共方法抽取 -- RequestBody格式     * @param: [jsonObject, platform]     * @return: com.alibaba.fastjson.JSONObject     * @author: zhouhong     * @date: 2023/5/17 11:00     */    JSONObject voiceRequestBodyCommonApi(JSONObject jsonObject, String platform);}
/** * @description: 语音公共方法抽离 * @author: zhouhong * @date: 2023/5/17 11:00 * @version: 1.0 */@Service@Log4j2public class VoiceCommonApiServiceImpl implements VoiceCommonApiService {    @Resource    private VoiceStrategyContext voiceStrategyContext;    @Override    public JSONObject voiceRequestBodyCommonApi(JSONObject jsonObject, String platform) {        log.info("大量逻辑校验代码......");        voiceStrategyContext.executeStrategyByKey(platform, jsonObject);        log.info("其他业务代码......");        return null;    }}

优化完工

四.设计模式总结1.简介

策略模式是一种行为型设计模式,它允许在运行时选择算法的行为。该模式将不同的算法封装在各自独立的策略类中,使得它们可以互相替换,而不会影响到客户端代码。

2.主要参与角色

环境类(Context):环境类持有一个策略对象,并在需要执行算法时调用策略对象的方法。它提供了一个接口供客户端代码设置策略对象。

抽象策略类(Strategy):定义了策略对象的接口或抽象类。它描述了算法的通用行为,可以包含算法的输入参数。

具体策略类(Concrete Strategy):实现了策略接口或继承了抽象策略类,并提供了具体的算法实现

3.工作流程

客户端代码创建一个环境对象(Context)。

客户端根据需求选择一个具体策略类,并将其设置到环境对象中。

环境对象在需要执行算法的时候,调用所持有的策略对象的方法。

策略对象根据自身的算法实现进行处理,并返回结果给环境对象。

客户端通过环境对象获取算法的结果。

4.使用场景

多种算法选择:当有多个算法可供选择,且需要在运行时动态选择其中一种算法时,可以使用策略模式。例如,在图像处理中,可以根据不同的要求选择不同的压缩算法。

避免条件语句:当代码中存在大量的条件语句用于根据不同条件执行不同的行为时,可以考虑使用策略模式来替代这些条件语句。策略模式将每种行为封装在单独的策略类中,使代码更加清晰、可维护。

动态配置行为:当需要动态地配置对象的行为时,可以使用策略模式。例如,在电商系统中,可以根据用户的会员级别,动态选择不同的折扣策略。

可扩展性:策略模式提供了一种可扩展的方式,允许添加新的策略类来满足新的需求,而无需修改现有代码。这种灵活性使得策略模式在需要频繁添加新的算法或行为的情况下非常有用。

单一职责原则:策略模式可以将不同的算法或行为分离到各自的策略类中,遵循了单一职责原则,使得每个类只关注自己的策略实现。

5.优缺点

优点:

提供了一种清晰的方式来管理不同算法的实现,并将其与客户端代码解耦。策略类可以灵活地替换和扩展,不会对客户端代码造成影响。提高了代码的可维护性和可读性,减少了大量的条件语句。

缺点:

增加了类的数量,每个具体策略类都需要单独实现一个类。五.示例代码地址

https://github.com/Tom-shushu/work-study.git 代码中的design-pattern 项目

标签:

(责任编辑:)

相关文章

每日热议!实际业务中使用策略模式对代码进行重构

​一 业务描述最近在负责公司一个语音的微服务模块优化,这个模块主要的业务是:1 天猫精灵、小度、若琪、小

2023-05-20 15:25:02

发条朋友圈轻松赚一百?支付宝官方辟谣_全球百事通

​“朋友圈出租”广告截图。(供图 网络)“支付宝招线上推广了,没前期费用,工资一星期700元先结一半,每天

2023-05-20 14:27:28

乌鸡汤怎么炖好喝又营养?

​步骤 方式1乌鸡半个生姜5克红枣15克莲子15克盐3克枸杞10克花旗参5克无花果10克步骤 方式2乌鸡清水清洗干净

2023-05-20 13:24:44

每日快播:什么是安全期和危险期_什么是安全

​1、答:随着人类社会的发展,安全已成为人类求得生存和发展的最基本条件,为整个人类所共识。2、安全含义一

2023-05-20 12:06:37

天天微头条丨河南许昌2.9级地震 3级地震什么感觉(今日/头条)

​一、河南许昌2 9级地震中国地震台网正式测定:05月20日09时03分在河南许昌市长葛市(北纬34 26度,东经113

2023-05-20 11:03:01

美国商品期货交易委员会(CFTC):截至5月16日当周,投机者将CBOT美国2年期国债期货净空头持仓增加103690手-环球快讯

​美国商品期货交易委员会(CFTC):截至5月16日当周,投机者将COT美国2年期国债期货净空头持仓增加103690手

2023-05-20 10:31:49

Netflix 版《美猴王》动画电影定档 8 月 18 日,周星驰监制|天天热推荐

​感谢指股网网友雨雪载途、华南吴彦祖、你好啊_兔子、指股网从官方获取到,该片由安东尼?斯塔奇(《盒子怪》

2023-05-20 09:44:10

维罗尼卡坎贝尔布朗_维罗尼卡坎贝尔布朗

​当前大家对于维罗尼卡·坎贝尔·布朗都是颇为感兴趣的,大家都想要了解一下维罗尼卡·坎贝尔·布朗,那么小

2023-05-20 08:58:25

夏枯草的功能与主治_夏菇草|环球速讯

​1、夏枯草可以清泻肝火、清头目,可以单用也可以和其他的药物同用,夏枯草用于痰火郁结所导致的瘰疬、瘿瘤

2023-05-20 07:41:14

全球热议:博硕科技(300951):5月19日北向资金减持1.2万股

​5月19日北向资金减持1 2万股博硕科技。近5个交易日中,获北向资金增持的有2天,累计净增持6100 0股。近20个

2023-05-20 06:44:25

泡泡玛特(09992.HK):5月19日南向资金减持125.9万股

​5月19日北向资金减持125 9万股泡泡玛特(09992 HK)。近5个交易日中,获南向资金减持的有2天,累计净减持12

2023-05-20 05:30:57

环球快看点丨电脑无限弹窗代码大全 电脑无限弹窗代码

​今天来聊聊关于电脑无限弹窗代码大全,电脑无限弹窗代码的文章,现在就为大家来简单介绍下电脑无限弹窗代码

2023-05-20 03:22:01

六哲最新的歌曲_六哲最新歌曲

​1、总共29首1相爱分开都是罪2被伤过的心还可以爱谁3错错错4我好喜欢你5心伤20106会受伤的人只有一种可能7多

2023-05-20 01:00:41

通讯!印度交易商削减黄金折扣,金价下跌重新吸引一些买盘

​一些日本交易商也以与全球价格持平的价格出售黄金,而另一些交易商则收取0 50美元的溢价

2023-05-19 22:41:02

宋的车标是什么车(车标是个宋字是什么车)

​本文目录一览:1、宋字车标是什么车2、车标是个宋字是什么车宋字车标是什么车1、宋字历哪车标是比亚迪宋

2023-05-19 22:01:49

多彩贵州推广文化旅游 发出夏游避暑邀约

​多彩贵州推广文化旅游发出夏游避暑邀约---5月19日,“有福有贵福贵双全”2023多彩贵州文化旅游推广暨招商推

2023-05-19 20:43:25

铭汉股份拟向银行申请不超过1000万贷款 公司实际控制人王照及子公司为该事项提供连带责任保证|全球讯息

​铭汉股份拟向银行申请不超过1000万贷款公司实际控制人王照及子公司为该事项提供连带责任保证,贷款,科学家,

2023-05-19 20:14:16

5·19中国旅游日|西双版纳分会场活动举行 文旅惠民开启幸福旅程

​紧扣西双版纳文旅资源、民族文化、非遗产品开展内容丰富的主题活动。

2023-05-19 19:20:23

《闪电侠》发布“双闪同行”预告片 冲破时空只为亲情永驻|世界快资讯

​由华纳兄弟影片公司发行的DC超级英雄电影《闪电侠》(TheFlash)今日发布“双闪同行”预告片,时空扭转、双闪

2023-05-19 18:55:18

当前看点!安鑫花借款逾期30年拖欠多久会上征信

​网贷逾期一般会上征信,有些借贷机构在用户逾期后一天后就会上报给征信机构,而有些借贷机构则是会在几天后

2023-05-19 17:52:32

当前视点!象州县气象台发布雷电黄色预警信号【III级/较重】【2023-05-19】

​象州县气象台2023年5月19日16时31分发布雷电黄色预警信号:预计未来6小时内象州县部分乡镇可能发生雷电活动

2023-05-19 17:27:50

功夫不负有心人的意思是什么_功夫不负有心人的意思_热头条

​1、“功夫不负有心人”是一句很有名的俗语(谚语)。2、意思是只要勤奋、认真地对待所做的事。3、就一定能

2023-05-19 16:59:43

吃“自助餐”,江边游泳嬉戏,亚洲象的生活也太让人羡慕了!_世界快看

​亚洲象是亚洲现存最大的陆生动物,它们食量大,为了觅食,亚洲象会根据食物的季节变化而移动。5月17日,记

2023-05-19 16:21:15

小吃店_关于小吃店介绍

​1、小吃店(SnackBar或Snacks)是专卖小吃零食的商店。2、多数开设人流旺盛的街道、旅游景点等,例如香港

2023-05-19 16:07:53

【西安白癜风专科医院】诱发老年白癜风的原因有哪些_每日焦点

​  【西安白癜风专科医院】诱发老年白癜风的原因有哪些?老年白癜风是指65岁或以上年龄段出现的白癜风。它

2023-05-19 15:20:28

雷阵雨,局地大风+冰雹!北京发布雷电黄色预警

​北京日报客户端|记者骆倩雯北京市气象台2023年5月19日14时30分发布雷电黄色预警信号:预计,当前至20时本市

2023-05-19 14:49:19

青岛银行与山东省非公协会战略合作 服务辖区北交所上市公司等

​青岛银行表示,未来将携手山东省非上市公众公司协会,为辖区北交所上市公司和新三板挂牌公司提供全方位、多

2023-05-19 14:03:58

每日看点!成都大运会筹备进入最后冲刺阶段

​本报成都5月18日电(记者周洪双、李晓东、王东)四川省成都市政府新闻办公室18日召开成都大运会总体筹办情

2023-05-19 13:11:56

世界即时看!加什么东西让头发猛长 什么可以让头发增多

​1、啤酒护发可以让头发猛长。先将头发洗净、擦干,然后将啤酒均匀地涂搽在头发上,并进行揉搓按摩,使其渗

2023-05-19 12:39:11

​推特称微软违反开发者协议,使用数据没有付费

​据报道,马斯克个人律师亚历克斯·斯皮罗代表Twitter致信微软CEO纳德拉,Twitter认为微软违反了Twitter开发

2023-05-19 11:57:13