当前位置: 首页 >  网技达人 >  实际业务中使用策略模式对代码进行重构

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

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

一.业务描述

最近在负责公司一个语音的微服务模块优化,这个模块主要的业务是: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 项目

内容
  • 初识Node和内置模块
    初识Node和内置模块
    2023-12-07
    初识Node与内置模块.概述:了解Node.js,熟悉内置模块:fs模块、path模块、http模块.初识Node.js
  • 企业内部培训网站为例,探索云上成本优化
    企业内部培训网站为例,探索云上成
    2023-12-07
    摘要: 本文就以一个企业内部培训网站为例,拆解云上成本优化方案需要注意的点,抛砖引玉,帮助大家参考业务架构,合理节省费用
  • 一种配置化的数据脱敏与反脱敏框架实现
    一种配置化的数据脱敏与反脱敏框架
    2023-12-07
    1.tony框架背景.在业务量日益剧增的背景下,大量数据在各种业务活动中产生,数据安全控制一直是治理的重要环节,数据脱敏
  • docker compose 快速安装 单机kafka版并且 持久化
    docker compose 快
    2023-12-05
    kafka 的业务场景不用多说了,耗时缓存队列,利用高吞吐以及队列模型实现 高并发情况下流量削峰,高流量的日志收集,都是
  • 业务数据“一站式”数据管理平台,从设备实时数据和业务应用数据两个方面要彻底解决“信息孤岛”的问题
    业务数据“一站式”数据管理平台,
    2023-12-02
    ** 1. 产品背景**.工业数据大致分为两种数据:设备实时数据和业务应用数据。.设备实时数据.的管理是iNeuOS工业
  • 万字好文:大报文问题实战
    万字好文:大报文问题实战
    2023-12-02
    导读.大报文问题,在京东物流内较少出现,但每次出现往往是大事故,甚至导致上下游多个系统故障。大报文的背后,是不同商家业务
  • 4.2 x64dbg 针对PE文件的扫描
    4.2 x64dbg 针对PE文
    2023-12-02
    通过运用LyScript插件并配合pefile模块,即可实现对特定PE文件的扫描功能,例如载入PE程序到内存,验证PE启
  • 一部软件开发科幻爽片:从数字化到低代码到自动代码生成
    一部软件开发科幻爽片:从数字化到
    2023-12-01
    摘要.企业数字化程度的一个核心体现就是业务团队与技术团队的融合程度。业务团队与技术团队的沟通越紧密,越理解对方的语言,企
  • 智能车载设备
    智能车载设备
    2023-10-02
    智能车载设备.我们的智能车载设备是一款结合了最新科技和创新设计的汽车配件,旨在提升驾驶体验、提高安全性和为用户带来智能化
  • 智能医疗设备
    智能医疗设备
    2023-10-02
    智能医疗设备产品介绍.智能医疗设备是一款集成了先进技术的高科技产品,旨在提高医疗保健的效率和质量。该设备主要应用于医院、
  • 互联网金融服务平台
    互联网金融服务平台
    2023-10-01
    互联网金融服务平台.产品功能.个人理财:用户可以通过平台进行投资理财,选择适合自己的理财产品,实现资金增值。.贷款服务:
  • 电子元件电感
    电子元件电感
    2023-10-02
    电子元件电感.产品功能.电感是一种重要的电子元件,用于储存和释放电能,调节电路中的电流和电压。它在电子设备和通讯设备中起
  • 智能智能家居设备
    智能智能家居设备
    2023-10-05
    智能家居设备介绍.产品概述.我们当前运营的产品是智能家居设备,它是一款智能化的家居控制系*,旨在为用户提供更便捷、舒适的
  • 智能可穿戴设备
    智能可穿戴设备
    2023-10-03
    产品功能介绍.我们的智能可穿戴设备是一款集健康监测、运动追踪、通讯互动等多种功能于一体的产品。它采用先进的传感技术,可实
  • 智能手机
    智能手机
    2023-10-01
    产品功能介绍:智能手机.智能手机是一款集通讯、娱乐、办公等功能于一体的移动智能设备。首先,智能手机具有强大的通讯功能,支
  • 智能智能物流设备
    智能智能物流设备
    2023-10-04
    智能物流设备.1. 产品描述.智能物流设备是一款基于物联网技术的智能设备,主要用于运输、储存和**物流货物。其核心功能是
  • 智能智能娱乐设备
    智能智能娱乐设备
    2023-10-04
    产品功能介绍.1. 智能娱乐设备.我们的智能娱乐设备是一款结合了智能技术和娱乐功能的产品。它拥有丰富的娱乐资源,包括音乐
  • 智能电视
    智能电视
    2023-10-01
    产品功能介绍.智能电视是一款结合了传统电视和智能硬件的产品。它内置了智能操作系*,能够连接互联网并运行各种应用程序。智能