springboot的if else过多解决方案

在实际开发工程中,常常会遇到多个ifelse的判断语句,对于简单的项目,还能够满足需求表。但是对于需求变更频繁的项目,这样会造成代码冗余同时且不易维护,不太建议采用这种方法。下面介绍一种springboot项目的解决方式。

1 基本代码

1.1service的接口代码

public interface OrderService {
    String handle(OrderDTO orderDTO);
}

1.2 OrderDTO代码

public class OrderDTO {
    private String code;
    private BigDecimal price;
    private String type;

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }
}

2两种实现方式

2.1传统方式

   public String traditionalHandle(OrderDTO orderDTO){
        String type = orderDTO.getType();
        if ("1".equals(type)){
            return "处理普通的类型";
        }if ("2".equals(type)){
            return "处理团购的类型";
        }if ("2".equals(type)){
            return "处理促销的类型";
        }
        return "错误处理";
    }

2.2策略模式


    @Autowired
    private HandlerContext handlerContext;
    @Override
    public String handle(OrderDTO orderDTO) {
        AbstractHandler handler = handlerContext.getInstance(orderDTO.getType());
        return handler.handler(orderDTO);
    }

3 策略+applicationContext容器方式

3.1实现思路

  1. 扫描对应的抽象类的多个实现类
  2. 将对应的实现类存储在hashMap容器中,并对外封装提供处理类
  3. 调用处理类完成业务需求

3.2代码实现

3.2.1HandlerProcessor 

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * @author shuxibing
 * @date 2019/7/31 15:03
 * @uint d9lab
 * @Description: 该类主要指将扫描的信息注入applicationContext容器中
 */
@Component
public class HandlerProcessor implements BeanFactoryPostProcessor {

    /**
     * 扫描hanglerMap注解兵注入容器中
     * @param beanFactory
     * @throws BeansException
     */
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        Map<String,Class> handlerMap=new HashMap<>(3);
        ClassScaner.scan(Const.HANDLER_PACAGER,HandlerType.class).forEach(clazz->{
            String type = clazz.getAnnotation(HandlerType.class).value();
            handlerMap.put(type,clazz);
        });
        HandlerContext context=new HandlerContext(handlerMap);
        beanFactory.registerSingleton(HandlerContext.class.getName(),context);
    }
}

3.2.2 AbstractHandler 和实现类

public abstract class AbstractHandler {
    public abstract String handler(OrderDTO orderDTO);
}
@Component
@HandlerType("1")
public class NormalHandler extends AbstractHandler {
    @Override
    public String handler(OrderDTO orderDTO) {
        return "处理普通订单";
    }
}
@Component
@HandlerType("2")
public class GroupHandler extends AbstractHandler {
    @Override
    public String handler(OrderDTO orderDTO) {
        return "处理团购的类型";
    }
}
@Component
@HandlerType("3")
public class PromotionHandler extends AbstractHandler {
    @Override
    public String handler(OrderDTO orderDTO) {
        return "处理团购订单";
    }
}

3.2.3 注解+扫描

@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
public @interface HandlerType {
    String value();
}
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternUtils;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.core.type.filter.TypeFilter;
import org.springframework.util.ClassUtils;
import org.springframework.util.SystemPropertyUtils;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.*;

/**
 * @author shuxibing
 * @date 2019/7/31 15:07
 * @uint d9lab
 * @Description:
 */
public class ClassScaner implements ResourceLoaderAware {
    private final List<TypeFilter> includeFilters=new LinkedList<>();
    private final List<TypeFilter> excludeFilters=new LinkedList<>();

    private ResourcePatternResolver resourcePatternResolver=new PathMatchingResourcePatternResolver();
    private MetadataReaderFactory metadataReaderFactory=new CachingMetadataReaderFactory(this.resourcePatternResolver);


    public static Set<Class<?>> scan(String[] basepackages, Class<? extends Annotation>...annoations) {
        ClassScaner cs=new ClassScaner();
        //需要扫描的注解
        if (ArrayUtils.isNotEmpty(annoations)){
            for (Class anno:annoations){
                cs.addIncludeFilter(new AnnotationTypeFilter(anno));
            }
        }
        Set<Class<?>> classes=new HashSet<>();
        for (String s:basepackages){
            classes.addAll(cs.doScan(s));
        }
        return classes;
    }
    public static Set<Class<?>> scan(String basePackage,Class<? extends Annotation> ...annoations){
        return scan(new String[]{basePackage},annoations);
    }

    private Set<Class<?>> doScan(String basePackage) {
        Set<Class<?>> classes=new HashSet<>();
        try {
            String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + ClassUtils.convertClassNameToResourcePath(SystemPropertyUtils.resolvePlaceholders(basePackage)) + "/**/*.class";
            Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath);
            for (Resource resource : resources) {
                if (resource.isReadable()){
                    MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(resource);
                    if ((includeFilters.size()==0&&excludeFilters.size()==0)||matches(metadataReader)){
                        try {
                            classes.add(Class.forName(metadataReader.getClassMetadata().getClassName()));
                        } catch (ClassNotFoundException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }catch (IOException e){
           throw new BeanDefinitionStoreException("IO failure during classpath scanning",e);
        }
        return classes;
    }

    protected boolean matches(MetadataReader metadataReader) throws IOException {
         for(TypeFilter tf:this.excludeFilters){
             if (tf.match(metadataReader,this.metadataReaderFactory)){
                 return false;
             }
         }
         for (TypeFilter tf:this.includeFilters){
             if (tf.match(metadataReader,this.metadataReaderFactory))
                return true;
         }
         return false;
    }

    /**
     * 设置解析器
     * @param resourceLoader
     */
    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourcePatternResolver= ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
        this.metadataReaderFactory=new CachingMetadataReaderFactory(resourceLoader);
    }



    public void addIncludeFilter(TypeFilter typeFilter){
        this.includeFilters.add(typeFilter);
    }

    public void addExcludeFilter(TypeFilter typeFilter){
        this.excludeFilters.add(0,typeFilter);
    }

    public final ResourceLoader getResourceLoader(){
        return this.resourcePatternResolver;
    }

    public void resetResourceLoader(){
        this.includeFilters.clear();
        this.excludeFilters.clear();
    }
}

3.2.4 封装获取applicationContext的对象类

@Component
public class BeanTool implements ApplicationContextAware {
    private static ApplicationContext applicationContext;
    //自动初始化注入applicationContext
    @Override
    public void setApplicationContext(ApplicationContext context) throws BeansException {
        if (applicationContext==null){
            applicationContext=context;
        }
    }

    /**通过bean的缩写的方式获取类型
     *
     * @param name
     * @return
     */
    public static Object getBean(String name){
        return applicationContext.getBean(name);
    }

    public static <T> T getBean(Class<T> clazz){
        return applicationContext.getBean(clazz);
    }
}

3.2.5 策略模式处理类

public class HandlerContext {
    private Map<String,Class> handlerMap;

    public HandlerContext(Map<String, Class> handlerMap) {
        this.handlerMap = handlerMap;
    }

    public AbstractHandler getInstance(String type){
        Class clazz=handlerMap.get(type);
        if (clazz==null){
            throw new IllegalArgumentException("输入的参数类型有问题:"+type);
        }
        return (AbstractHandler) BeanTool.getBean(clazz);
    }
}

3.2.6 参数类

public class Const {
    public static final String HANDLER_PACAGER="com.shu.example.strategymodel";
}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值