if else 优化 策略模式+工厂模式

简介: if else 优化 策略模式+工厂模式


if else 优化 策略模式+工厂模式

场景

    在项目中有时候会遇到需要大量if else判断的时候,通常的if else 判断会造成代码整体不够优雅,可读性差,
可维护性差,且后续交给新手维护的时候可能会让人蒙圈,因而会想到通过一种方法来对这种情况进行优化,提高
自己技术的同时也让自己参与的项目更便于维护,何乐而不为呢。

下面先看一下原始代码的写法,然后再提出优化后的代码,大家可以对比一下其中的不同


controller

image.png

controller通过依赖注入调用dialogueLogV3Service.saveDialogueLog(dialogueLog)方法;


service

image.png

service层通过依赖注入执行具体的业务逻辑方法


原始代码

  @Override
  @Transactional(rollbackFor = Exception.class)
  public int saveDialogueLog(DialogueLog dialogueLog) {
    //保存提交信息
    int i = insertDialogueLog(dialogueLog);
    //保存对话信息
    UserChatRecord userChatRecord = updateUserChatRecord(dialogueLog);
    if (Constants.QUESTION_TYPE.ONE.getValue().equals(dialogueLog.getType())){
      //业务逻辑代码......
    }else if(Constants.QUESTION_TYPE.TWO.getValue().equals(dialogueLog.getType())) {
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.THREE.getValue().equals(dialogueLog.getType())) {
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.FOUR.getValue().equals(dialogueLog.getType())) {
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.FIVE.getValue().equals(dialogueLog.getType())) {
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.SIX.getValue().equals(dialogueLog.getType())) {
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.SEVEN.getValue().equals(dialogueLog.getType())) {
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.EIGHT.getValue().equals(dialogueLog.getType())) {
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.NINE.getValue().equals(dialogueLog.getType())) {
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.TEN.getValue().equals(dialogueLog.getType())) {
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.ELEVEN.getValue().equals(dialogueLog.getType())) {
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.TWELVE.getValue().equals(dialogueLog.getType())) {
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.THIRTEEN.getValue().equals(dialogueLog.getType())) {
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.FOURTEEN.getValue().equals(dialogueLog.getType()) ||
        Constants.QUESTION_TYPE.TWENTY_SIX.getValue().equals(dialogueLog.getType()) ||
        Constants.QUESTION_TYPE.THIRTY_FOUR.getValue().equals(dialogueLog.getType()) ||
        Constants.QUESTION_TYPE.THIRTY_SEVEN.getValue().equals(dialogueLog.getType()) ||
        Constants.QUESTION_TYPE.SIXTEEN.getValue().equals(dialogueLog.getType()) ||
        Constants.QUESTION_TYPE.FIFTEEN.getValue().equals(dialogueLog.getType()) ||
        Constants.QUESTION_TYPE.TWENTY_SEVEN.getValue().equals(dialogueLog.getType()) ||
        Constants.QUESTION_TYPE.THIRTY_FIVE.getValue().equals(dialogueLog.getType()) ||
        Constants.QUESTION_TYPE.THIRTY_EIGHT.getValue().equals(dialogueLog.getType()) ||
        Constants.QUESTION_TYPE.TWENTY_NINE.getValue().equals(dialogueLog.getType())) {
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.SEVENTEEN.getValue().equals(dialogueLog.getType()) ||
        Constants.QUESTION_TYPE.EIGHTTEEN.getValue().equals(dialogueLog.getType())) {
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.NINETEEN.getValue().equals(dialogueLog.getType())) {
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.TWENTY.getValue().equals(dialogueLog.getType()) ||
        Constants.QUESTION_TYPE.TWENTY_FOUR.getValue().equals(dialogueLog.getType()) ||
        Constants.QUESTION_TYPE.TWENTY_ONE.getValue().equals(dialogueLog.getType()) ||
        Constants.QUESTION_TYPE.TWENTY_FIVE.getValue().equals(dialogueLog.getType()) ||
        Constants.QUESTION_TYPE.THIRTY_SIX.getValue().equals(dialogueLog.getType()) ||
        Constants.QUESTION_TYPE.THIRTY_NINE.getValue().equals(dialogueLog.getType())) {
            //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.TWENTY_TWO.getValue().equals(dialogueLog.getType()) ||
        Constants.QUESTION_TYPE.TWENTY_THREE.getValue().equals(dialogueLog.getType())) {
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.THIRTY.getValue().equals(dialogueLog.getType()) ||
        Constants.QUESTION_TYPE.THIRTY_ONE.getValue().equals(dialogueLog.getType())) {
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.THIRTY_TWO.getValue().equals(dialogueLog.getType()) ||
        Constants.QUESTION_TYPE.THIRTY_THREE.getValue().equals(dialogueLog.getType())) {
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.FORTY.getValue().equals(dialogueLog.getType()) ||
        Constants.QUESTION_TYPE.FORTY_ONE.getValue().equals(dialogueLog.getType())) {
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.FORTY_TWO.getValue().equals(dialogueLog.getType())) {
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.FORTY_FOUR.getValue().equals(dialogueLog.getType()) ||
        Constants.QUESTION_TYPE.FORTY_FIVE.getValue().equals(dialogueLog.getType()) ||
        Constants.QUESTION_TYPE.FORTY_SIX.getValue().equals(dialogueLog.getType())) {
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.FIFTY.getValue().equals(dialogueLog.getType())) {
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.FIFTY_ONE.getValue().equals(dialogueLog.getType())) {
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.FIFTY_TWO.getValue().equals(dialogueLog.getType())) {
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.FORTY_NINE.getValue().equals(dialogueLog.getType())){
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.FORTY_EIGHT.getValue().equals(dialogueLog.getType())){
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.FIFTY_THREE.getValue().equals(dialogueLog.getType())){
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.FIFTY_FOUR.getValue().equals(dialogueLog.getType())){
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.FIFTY_FIVE.getValue().equals(dialogueLog.getType())){
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.FIFTY_SIX.getValue().equals(dialogueLog.getType())){
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.FIFTY_SEVEN.getValue().equals(dialogueLog.getType()) ||
        Constants.QUESTION_TYPE.SIXTY.getValue().equals(dialogueLog.getType())){
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.FIFTY_EIGHT.getValue().equals(dialogueLog.getType())){
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.FIFTY_NINE.getValue().equals(dialogueLog.getType())){
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.SIXTY_ONE.getValue().equals(dialogueLog.getType())) {
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.SIXTY_THREE.getValue().equals(dialogueLog.getType()) ||
        Constants.QUESTION_TYPE.SIXTY_FOUR.getValue().equals(dialogueLog.getType())) {
      //业务逻辑代码......
    }else if (Constants.QUESTION_TYPE.SIXTY_FIVE.getValue().equals(dialogueLog.getType())) {
      //业务逻辑代码......
    }
    return i;
  }


可以看到有很多if else 判断,并且后续每增加一种类型,这里就需要加一个else if 判断,后面开发这阅读起来单从方法行数上就有点蒙圈了,具体业务逻辑更是难懂了,很不利于后期维护。


策略模式+工厂模式

鉴于以上的情况,于是考虑通过设计模式的方向解决代码量大,阅读困难,维护成本高的问题


解决方案

基于当前业务区分主要与QUESTION_TYPE  相关,不同的QUESTION_TYPE对应不同的业务处理逻辑。那么套用策略模式的描述就是说一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为;或者说是一个类的行为或其算法可以在运行时更改。


创建一个接口

声明业务处理方法operation

public interface QuestionTypeService {
    /**
     * 业务操作方法
     */
    public void operation(Object object);
}


创建QUESTION_TYPE 对应的实现类

实现接口声明方法中的具体业务逻辑


QUESTION_TYPE实现类一

@Service
public class QuestionOneServiceImpl implements QuestionTypeService {
    @Override
    public void operation(Object object) {
        //具体的业务处理逻辑
    }
}
@Service
public class QuestionTwoServiceImpl implements QuestionTypeService {
    @Override
    public void operation(Object object) {
        //具体的业务处理逻辑
    }
}
............


QUESTION_TYPE实现类二

@Service
public class QuestionOneServiceImpl implements QuestionTypeService {
    @Autowired
    private UserPhysicalLogMapper userPhysicalLogMapper;
    @PostConstruct
    public void init() {
        BusinessFactory.register(Constants.QUESTION_TYPE.ONE.getValue(),this);
    }
    @Override
    public void operation(Object object) {
         //具体的业务处理逻辑
    }
}
@Service
public class QuestionTwoServiceImpl implements QuestionTypeService {
    @Autowired
    private ITimingMessageService timingMessageService;
    @PostConstruct
    public void init() {
        BusinessFactory.register(Constants.QUESTION_TYPE.TWO.getValue(),this);
    }
    @Override
    public void operation(Object object) {
        //具体业务处理逻辑
    }
}
............

此方法@Service表明该类将自动注册到Spring容器


创建BusinessFactory工厂类

工厂模式通俗理解就是说我不需要知道具体产品是怎么生产出来的,我只需要知道我需要什么产品然后从工厂提货就可以了,这里我告诉工厂我需要QuestionOneServiceImpl,然后工厂替我创建好对应的bean并交给spring管理


工厂类一

@Component
public class BusinessFactory {
    public QuestionTypeService getQuestionType(Integer type){
        if(type == null){
            return null;
        }
        if(Constants.QUESTION_TYPE.ONE.getValue().equals(type)){
            return SpringUtils.getBean(QuestionOneServiceImpl.class);
        }
        return null;
    }
}


工厂类二

@Component
public class BusinessFactory {
    private static Map<Integer,QuestionTypeService> map = new HashMap(128);
    public static void register(Integer type,QuestionTypeService questionTypeService) {
        map.put(type,questionTypeService);
    }
    /**
     * 获取业务实现类
     * @param type
     * @return
     */
    public QuestionTypeService getQuestionType(Integer type){
        if(type == null){
            return null;
        }
        return map.get(type);
    }
}

此方法@Component表明该类将自动注册到Spring容器,此处用SpringUtils.getBean(QuestionOneServiceImpl.class);   或者SpringUtils.getBean(“questionOneServiceImpl”);而来获取子项实例是将获取的子项实例交给spring容器,这样避免直接new对象的时候后续需要依赖注入对象时为null的问题。


SpringUtils.java

package com.ruoyi.common.utils.spring;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
/**
 * spring工具类 方便在非spring管理环境中获取bean
 * 
 */
@Component
public final class SpringUtils implements BeanFactoryPostProcessor
{
    /** Spring应用上下文环境 */
    private static ConfigurableListableBeanFactory beanFactory;
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException
    {
        SpringUtils.beanFactory = beanFactory;
    }
    /**
     * 获取对象
     *
     * @param name
     * @return Object 一个以所给名字注册的bean的实例
     * @throws org.springframework.beans.BeansException
     *
     */
    @SuppressWarnings("unchecked")
    public static <T> T getBean(String name) throws BeansException
    {
        return (T) beanFactory.getBean(name);
    }
    /**
     * 获取类型为requiredType的对象
     *
     * @param clz
     * @return
     * @throws org.springframework.beans.BeansException
     *
     */
    public static <T> T getBean(Class<T> clz) throws BeansException
    {
        T result = (T) beanFactory.getBean(clz);
        return result;
    }
    /**
     * 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true
     *
     * @param name
     * @return boolean
     */
    public static boolean containsBean(String name)
    {
        return beanFactory.containsBean(name);
    }
    /**
     * 判断以给定名字注册的bean定义是一个singleton还是一个prototype。 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException)
     *
     * @param name
     * @return boolean
     * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
     *
     */
    public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException
    {
        return beanFactory.isSingleton(name);
    }
    /**
     * @param name
     * @return Class 注册对象的类型
     * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
     *
     */
    public static Class<?> getType(String name) throws NoSuchBeanDefinitionException
    {
        return beanFactory.getType(name);
    }
    /**
     * 如果给定的bean名字在bean定义中有别名,则返回这些别名
     *
     * @param name
     * @return
     * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
     *
     */
    public static String[] getAliases(String name) throws NoSuchBeanDefinitionException
    {
        return beanFactory.getAliases(name);
    }
    /**
     * 获取aop代理对象
     * 
     * @param invoker
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T> T getAopProxy(T invoker)
    {
        return (T) AopContext.currentProxy();
    }
}


业务调用

优化后代码

  @Override
  @Transactional(rollbackFor = Exception.class)
  public int saveDialogueLog(DialogueLog dialogueLog) {
    //保存提交信息
    int i = insertDialogueLog(dialogueLog);
    //保存对话信息
    UserChatRecord userChatRecord = updateUserChatRecord(dialogueLog);
    QuestionTypeService questionTypeService = businessFactory.getQuestionType(dialogueLog.getType());
    questionTypeService.operation(dialogueLog);
        return i;
  }

这样就将每一种判断分开来而不用造成一个巨大臃肿的方法造成维护阅读两难的困境。


相关文章
|
XML Java 应用服务中间件
SpringBoot-打包&部署
SpringBoot 项目支持两种打包方式:WAR 包和 JAR 包。JAR 包内置 Tomcat,可直接运行;WAR 包需部署在外部 Tomcat 上。JAR 包通过 `mvn clean package` 打包并用 `java -jar` 运行,支持后台运行和 JVM 参数配置。WAR 包需修改 pom.xml 为 war 类型,移除嵌入式 Tomcat 依赖,添加 servlet-api,并继承 `SpringBootServletInitializer`。配置文件可通过外部 application.yml 覆盖,默认优先级高于 JAR 内部配置。
1473 17
SpringBoot-打包&部署
|
canal 缓存 NoSQL
Redis缓存与数据库如何保证一致性?同步删除+延时双删+异步监听+多重保障方案
根据对一致性的要求程度,提出多种解决方案:同步删除、同步删除+可靠消息、延时双删、异步监听+可靠消息、多重保障方案
Redis缓存与数据库如何保证一致性?同步删除+延时双删+异步监听+多重保障方案
|
消息中间件
十一、RabbitMQ高级 - 延迟队列
十一、RabbitMQ高级 - 延迟队列
|
安全 网络安全 数据安全/隐私保护
轻松部署SFTP并解决连接未设置密钥的报错
尊敬的读者们,大家好!SFTP是一种基于SSH的加密文件传输协议,可确保您的数据在传输过程中得到保护,是一种可信赖的文件传输解决方案。在实际生产环境中,连接第三方SFTP服务器是许多企业进行文件传输的常见需求。然而,有时候当第三方SFTP服务器切换节点后,我们的服务连接却会出现失败的情况。我们今天就遇到了这种情况,第三方服务因国产化需求切换到了新的节点,导致我们的服务连接sftp服务器失败。在本文中,我将与您分享这个问题的原因以及解决方法以及如何使用Docker Compose快速部署SFTP(Secure File Transfer Protocol)服务,帮助您轻松应对类似的挑战。
675 0
轻松部署SFTP并解决连接未设置密钥的报错
|
Java Spring 容器
《SpringBoot系列十四》:@ConditionalOnBean、@ConditionalOnMissingBean注解居然失效了
《SpringBoot系列十四》:@ConditionalOnBean、@ConditionalOnMissingBean注解居然失效了
2093 0
《SpringBoot系列十四》:@ConditionalOnBean、@ConditionalOnMissingBean注解居然失效了
|
设计模式 Java
【SpringBoot】如何使用策略模式+抽象工厂+反射
【SpringBoot】如何使用策略模式+抽象工厂+反射
509 2
|
Ubuntu 安全 Linux
Linux安装phpstudy
为服务器环境提供极佳配置的解决方案 支持CentOS、Ubuntu、Debian、Fedora、deepin,Web端管理,QQ群及论坛技术支持 一键创建网站、FTP、数据库、SSL;安全管理,计划任务,文件管理,PHP多版本共存及切换;自带LNMP与LAMP
Linux安装phpstudy
|
存储 安全 程序员
智能硬件如何保证其安全性?信任根(RoT)是关键
首席信息官、首席信息安全官和 IT 决策者需要意识到他们的系统非常脆弱,尤其是在固件级别。需要的是硬件信任根,它可用于验证和授权任何堆栈级别的任何更改,同时保持足够的灵活性以适应新的漏洞并启用安全应用程序。固件攻击只会随着黑客变得更加雄心勃勃而增加,我们应对此有所作为。
1116 0
智能硬件如何保证其安全性?信任根(RoT)是关键
|
API
JDK8函数式接口之Function
JDK8函数式接口之Function
468 0

热门文章

最新文章

下一篇
开通oss服务