实际业务中使用策略模式对代码进行重构

这篇具有很好参考价值的文章主要介绍了实际业务中使用策略模式对代码进行重构。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一.业务描述

最近在负责公司一个语音的微服务模块优化,这个模块主要的业务是: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
@Log4j2
public class AliGenieServiceImpl implements VoiceStrategyService {
    @Override
    public JSONObject operateApi(JSONObject jsonObject) {
        log.info("天猫精灵-设备发现/控制成功!");
        return null;
    }
}
@Service
@Log4j2
public class DuerOSServiceImpl implements VoiceStrategyService {
    @Override
    public JSONObject operateApi(JSONObject jsonObject) {
        log.info("小度-设备发现/控制成功!");
        return null;
    }
}
@Service
@Log4j2
public class RokidServiceImpl implements VoiceStrategyService {
    @Override
    public JSONObject operateApi(JSONObject jsonObject) {
        log.info("若琪-设备发现/控制成功!");
        return null;
    }
}
@Service
@Log4j2
public 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
@Log4j2
public 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.主要参与角色

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

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

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

3.工作流程

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

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

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

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

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

4.使用场景

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

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

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

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

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

5.优缺点

优点:

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

缺点:

  • 增加了类的数量,每个具体策略类都需要单独实现一个类。

五.示例代码地址

https://github.com/Tom-shushu/work-study.git    代码中的 design-pattern 项目文章来源地址https://www.toymoban.com/news/detail-451587.html

到了这里,关于实际业务中使用策略模式对代码进行重构的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 实际开发中常用的设计模式--------单例模式(知识跟业务场景结合)-----小白也能看懂(通俗易懂版本)

    1.定义 单例模式是一种创建型设计模式,它通过使用私有构造函数和静态方法来确保一个类只有一个实例,并且提供全局访问点来获取该实例。 通过使用单例模式,我们可以方便地管理全局唯一的对象实例,并且避免了多次创建相同类型的对象所带来的资源浪费问题 2.业务场

    2024年02月12日
    浏览(12)
  • react useState useEffect useMemo实际业务场景中的使用

    react useState useEffect useMemo实际业务场景中的使用

    下面的代码实现了上面图片的功能

    2024年02月16日
    浏览(15)
  • 【Java设计模式 规范与重构】 二 重构的保障:单元测试,以及如何提高代码可测试性

    其实之前的工作中强调过很多次自己做测试的重要性,例如讲单元测试的: 【C#编程最佳实践 一】单元测试实践 ,讲单元测试规范的 【阿里巴巴Java编程规范学习 四】Java质量安全规约 ,讲接口测试的: 【C#编程最佳实践 十三】接口测试实践 ,这里旧事重提就不再详细展开

    2023年04月25日
    浏览(64)
  • 同城售后系统退款业务重构心得

    到家、小时购、天选退款有 2套 结构,代码逻辑混乱; 其中小时购、天选部分售后单是和平生pop交互退款,部分是和售后中台交互退款;并且 兼容3套 逻辑; 痛点 :代码繁重,缺乏合理性的设计,后续迭代 开发 以及 维护成本高 ,同时增加了系统的 风险和不稳定性 到家、

    2024年02月06日
    浏览(13)
  • 【设计模式之美】重构(三)之解耦方法论:如何通过封装、抽象、模块化、中间层等解耦代码?

    【设计模式之美】重构(三)之解耦方法论:如何通过封装、抽象、模块化、中间层等解耦代码?

    重构可以分为大规模高层重构(简称“大型重构”)和小规模低层次重构(简称“小型重构”)。 通过解耦对代码重构,就是保证代码不至于复杂到无法控制的有效手段。   代码是否需要“解耦”? 看修改代码会不会牵一发而动全身。 依赖关系是否复杂 把模块与模块之间

    2024年01月16日
    浏览(14)
  • 策略模式代码示例(二)

    一、定义 策略模式,针对每一个不同的类型,调用具有共同接口的不同实现类,从而使得它们可以相互替换。 策略模式 ,针对实现同一接口的不同的类,采用不同的策略。比如,面对高级会员、初级会员会采用不同的折扣。 策略模式,可以避免大量的if和else。 二、角色 策

    2024年03月08日
    浏览(10)
  • 策略模式详解+代码案例

    首先简单介绍策略模式 该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管

    2024年04月17日
    浏览(6)
  • Zinx框架-游戏服务器开发002:框架学习-按照三层结构模式重构测试代码+Tcp数据适配+时间轮定时器

    Zinx框架-游戏服务器开发002:框架学习-按照三层结构模式重构测试代码+Tcp数据适配+时间轮定时器

    三层结构重构原有功能 自定义消息类,继承UserData,添加一个成员变量szUserData 定义多个Role类继承Irole,重写ProcMsg函数,进行不同处理 定义protocol类,继承Iprotocol,重写四个函数,两个函数时原始 数据和用户数据之间的转换;另两个用来找消息处理对象和消息发 送对象。 定

    2024年02月05日
    浏览(17)
  • 一行代码搞定Spring策略模式,强的离谱

    在Spring中大量使用策略模式来简化 if/else 代码,比如Spring Security 的各种 AuthenticationProvider 等等,但是实现方式过于麻烦,使用重复套路来实现。 场景:关于用户订单充值(订单支付同理),我们都知道,现今的支付方式是非常的多的,例如:支付宝、微信、银联、钱包(各个

    2024年02月07日
    浏览(12)
  • 设计模式之策略模式:让你的代码灵活应对不同的算法

    作为一个程序员,我们经常会面临着在不同的情况下选择不同的算法来解决问题的需求。这种情况下,策略模式是一个非常有用的设计模式。在本文中,我将向你介绍策略模式的概念、结构以及如何应用这个模式来使你的代码更灵活。 策略模式是一种行为型设计模式,它允许

    2024年02月08日
    浏览(5)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包