前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >if else 优化 策略模式+工厂模式

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

作者头像
六月的雨在Tencent
发布2024-03-28 20:54:43
960
发布2024-03-28 20:54:43
举报
文章被收录于专栏:CSDN
if else 优化 策略模式+工厂模式

场景

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

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

controller

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

service

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

原始代码

代码语言:javascript
复制
	@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

代码语言:javascript
复制
public interface QuestionTypeService {

    /**
     * 业务操作方法
     */
    public void operation(Object object);
}
创建QUESTION_TYPE 对应的实现类

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

QUESTION_TYPE实现类一
代码语言:javascript
复制
@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实现类二
代码语言:javascript
复制
@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管理

工厂类一
代码语言:javascript
复制
@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;
    }
}
工厂类二
代码语言:javascript
复制
@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
代码语言:javascript
复制
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();
    }
}

业务调用

优化后代码

代码语言:javascript
复制
	@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;
	}

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-03-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • if else 优化 策略模式+工厂模式
  • 场景
    • controller
      • service
        • 原始代码
        • 策略模式+工厂模式
          • 解决方案
            • 创建一个接口
            • 创建QUESTION_TYPE 对应的实现类
            • 创建BusinessFactory工厂类
            • SpringUtils.java
        • 业务调用
          • 优化后代码
          相关产品与服务
          容器服务
          腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档