使用自定义注解和策略模式去掉if-else

Posted bulrush

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用自定义注解和策略模式去掉if-else相关的知识,希望对你有一定的参考价值。

一:写自定义注解

package com.wing.cloud.base.modular.strategy;

import java.lang.annotation.*;

/**
 * <p>
 *     自定义策略注解
 * </p>
 *
 * @author: heluwei
 * @Date: 2020/4/22 17:52
 */
@Target(ElementType.TYPE)  //作用在类上
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited  //子类可以继承此注解
public @interface HandlerOrderType {
    /**
     * 策略类型
     */
    int value();
}

二:if-else的类型

package com.wing.cloud.base.modular.entity;

import lombok.Builder;
import lombok.Data;

/**
 * <p>
 *     if-else的条件
 * </p>
 *
 * @author: heluwei
 * @Date: 2020/4/22 17:53
 */
@Data
@Builder
public class OrderType {
    //免费订单
    public static final int FREE = 1;
    //半价订单
    public static final int HALF = 2;
    //打折订单
    public static final int DISCOUT = 3; 
}

三:定义所有的类型策略

package com.wing.cloud.base.modular.strategy;

/**
 * <p>
 *      定义else的策略接口
 * </p>
 *
 * @author: heluwei
 * @Date: 2020/4/22 17:54
 */
public interface OrderStrategy {
    void handleOrder(Integer type);
}

三个条件实现其接口

package com.wing.cloud.base.modular.strategy;

import com.wing.cloud.base.modular.entity.OrderType;
import org.springframework.stereotype.Component;

/**
 * <p>
 *     实现策略接口
 * </p>
 *
 * @author: heluwei
 * @Date: 2020/4/22 17:55
 */
@Component
@HandlerOrderType(OrderType.FREE) //使用注解标明策略类型
public class FreeOrderStrategy implements OrderStrategy {
    @Override
    public void handleOrder(Integer order) {
        System.out.println("----处理免费订单----");
    }
}
package com.wing.cloud.base.modular.strategy;

import com.wing.cloud.base.modular.entity.OrderType;
import org.springframework.stereotype.Component;

/**
 * <p>
 *      实现策略接口
 * </p>
 *
 * @author: heluwei
 * @Date: 2020/4/22 17:55
 */
@Component
@HandlerOrderType(OrderType.DISCOUT)
public class DiscoutOrderStrategy implements OrderStrategy {
    @Override
    public void handleOrder(Integer order) {
        System.out.println("----处理打折订单----");
    }
}
package com.wing.cloud.base.modular.strategy;

import com.wing.cloud.base.modular.entity.OrderType;
import org.springframework.stereotype.Component;

/**
 * <p>
 *     实现策略接口
 * </p>
 *
 * @author: heluwei
 * @Date: 2020/4/22 17:55
 */
@Component
@HandlerOrderType(OrderType.HALF)
public class HalfOrderStrategy implements OrderStrategy {
    @Override
    public void handleOrder(Integer order) {
        System.out.println("----处理半价订单----");
    }
}

四:把策略实现类存放到spring容器中

package com.wing.cloud.base.modular.strategy;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * <p>
 *     自定义spring处理器。把所有的策略类存储到Map集合中。
 * </p>
 *
 * @author: heluwei
 * @Date: 2020/4/22 17:58
 */
@Component
public class HandlerOrderProcessor implements ApplicationContextAware {
    /**
     * 获取所有的策略Beanclass 加入HandlerOrderContext属性中
     * @param applicationContext
     * @throws BeansException
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        //获取所有策略注解的Bean
        Map<String, Object> orderStrategyMap = applicationContext.getBeansWithAnnotation(HandlerOrderType.class);
        orderStrategyMap.forEach((k,v)->{
            //获取策略实现类
            Class<OrderStrategy> orderStrategyClass = (Class<OrderStrategy>) v.getClass();
            //获取策略实现类的注解值。
            int type = orderStrategyClass.getAnnotation(HandlerOrderType.class).value();
            //将class加入HandlerOrderContext的map中,type作为key
            HandlerOrderContext.orderStrategyBeanMap.put(type,orderStrategyClass);
        });
    }
}
package com.wing.cloud.base.modular.strategy;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

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

/**
 * <p></p>
 *
 * @author: heluwei
 * @Date: 2020/4/22 17:57
 */
@Component
public class HandlerOrderContext {
    @Autowired
    private ApplicationContext applicationContext;
    //存放所有策略类Bean的map
    public static Map<Integer, Class<OrderStrategy>> orderStrategyBeanMap= new HashMap<>();

    public OrderStrategy getOrderStrategy(Integer type){
        Class<OrderStrategy> strategyClass = orderStrategyBeanMap.get(type);
        if(strategyClass==null){
            throw new IllegalArgumentException("没有对应的订单类型");
        }
        //从容器中获取对应的策略Bean
        return applicationContext.getBean(strategyClass);
    }
}

五:Service写业务逻辑

package com.wing.cloud.base.modular.service;


/**
 * <p>
 *     把写的策略模式在Service业务类中运用。
 * </p>
 *
 * @author: heluwei
 * @Date: 2020/4/22 18:01
 */
public interface OrderService {
    void handleOrder(Integer orderType);
}
package com.wing.cloud.base.modular.service.impl;

import com.wing.cloud.base.modular.service.OrderService;
import com.wing.cloud.base.modular.strategy.HandlerOrderContext;
import com.wing.cloud.base.modular.strategy.OrderStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * <p></p>
 *
 * @author: heluwei
 * @Date: 2020/4/22 18:02
 */
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    HandlerOrderContext handlerOrderContext;
    @Override
    public void handleOrder(Integer type) {
        //使用策略处理订单
        OrderStrategy orderStrategy = handlerOrderContext.getOrderStrategy(type);
        orderStrategy.handleOrder(type);
    }
}

六:测试

@Test
    public void testStrategy(){
        orderService.handleOrder(1);
    }

技术图片

 

以上是关于使用自定义注解和策略模式去掉if-else的主要内容,如果未能解决你的问题,请参考以下文章

自定义注解+策略模式,实现不同表的写操作!

小白写了一堆if-else,大神实在看不下去了,竟然用策略模式直接摆平了

Java使用函数式接口处理if-else的策略模式

使用策略模式+工厂模式干掉代码中过多的if-else

使用策略模式+工厂模式干掉代码中过多的if-else

使用策略模式+工厂模式干掉代码中过多的if-else