利用Spring和SpringBoot理念减少if else

1.项目中注入SpringBeanUtils

springBoot理念就是约定大于配置,其实经常写代码我们经常看到if else代码,今天介绍一种约定大于配置的方法减少if else。首先项目中要拿到Spring的ApplicationContext ,方便我们后面获取容器中的Bean

public class SpringBeanContextUtil implements ApplicationContextAware{
    /**  */
    private static ApplicationContext applicationContext;
    
    @Override
    public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException {
        if (SpringBeanContextUtil.applicationContext == null) {
            SpringBeanContextUtil.applicationContext = applicationContext;
        }
    }
    
    /**
     * @return xx
     */
    public static ApplicationContext getApplicationContext() {
        return SpringBeanContextUtil.applicationContext;
    }
    
    /**
     * @param name xx
     * @return xx
     */
    public static Object getBean(final String name) {
        Object obj = null;
        try {
            obj = getApplicationContext().getBean(name);
        } catch (BeansException e) {
            return obj;
        }
        return obj;
    }
    
    /**
     * @param <T> xx
     * @param clazz xx
     * @return xx
     */
    public static <T> T getBean(final Class<T> clazz) {
        T obj = null;
        try {
            obj = getApplicationContext().getBean(clazz);
        } catch (BeansException e) {
            return obj;
        }
        return obj;
    }
    
    /**
     * @param <T> xx
     * @param name xx
     * @param clazz xx
     * @return xx
     */
    public static <T> T getBean(final String name, final Class<T> clazz) {
        T obj = null;
        try {
            obj = getApplicationContext().getBean(name, clazz);
        } catch (BeansException e) {
            return obj;
        }
        return obj;
    }
}

2.示例代码

       if (SaleOrderStatusEnum.WAITING_PAY.getCode()==orderInfo.getOrderStatus()){
            // 处理待支付逻辑
        }else if(SaleOrderStatusEnum.WAITING_DELIVERY.getCode()==orderInfo.getOrderStatus()){
            // 处理待发货逻辑
        }else if(SaleOrderStatusEnum.WAITING_AUDIT.getCode()==orderInfo.getOrderStatus()){
            // 处理审核逻辑
        }

上面代码大概就是根据订单状态处理业务逻辑,尤其很多判断的时候需要写很多if else;

3. 改造代码

  • 现在我们发现每种状态都需要判断之后,然后处理逻辑,我们需要将这些逻辑抽象为一个接口
public interface OrderStatusDealService {

	// 事件处理服务
   void executeBusinessByOrderStatus(OrderInfo orderInfo)
}

  • 实现上面的接口,将上面的if else中的内容抽象成一个一个组件,相当于策略模式中的具体策略
// 处理待支付服务
@Slf4j
@Service("OrderStatusService_"+"WaitPay")
public class WaitPayOrderService implements OrderStatusDealService {

@Override
public void executeBusinessByOrderStatus(OrderInfo orderInfo){
	//处理待支付逻辑
}
}
// 处理待发货服务
@Slf4j
@Service("OrderStatusService_"+"WaitDelivery")
public class WaitDeliveryOrderService implements OrderStatusDealService {
@Override
public void executeBusinessByOrderStatus(OrderInfo orderInfo){
		//处理待发货逻辑
	}
}

注意@Service对组件的命名,其中WaitDelivery,WaitPay为上面if中判断的状态,其实就是订单的状态(实际中可能是数字,可以做一层转换或者可以利用前缀+状态命名好各个组件)

4.如何使用这些业务组件

在业务代码中直接根据订单状态获取Spring容器中对应的Bean进行处理业务处理

// 业务使用地方,直接根据订单状态获取容器中对应的处理类
public void dealBusiness(OrderInfo orderInfo){
    OrderStatusDealService orderStatusDealService     = SpringBeanContextUtil.getBean("OrderStatusService_" + orderInfo.getOrderStatus(), OrderStatusDealService.class);
   // 处理业务
   orderStatusDealService.executeBusinessByOrderStatus(OrderInfo orderInfo);
    }

好处:

  • 比如传入了订单状态是WaitPay,那么获取到的组件是OrderStatusService_WaitPay。这样就拿到我们的待支付处理组件。避免写了大量的if else,
  • 后面我们开发另外一种订单状态处理业务直接根据约定的(配置好名称名称)去开发,而不要去维护if else判断,这里业务组件相当于策略模式中的具体策略,尤其是当我们有大量状态判断之后再去处理业务逻辑的时候。约定好我们的Bean名称以某种自定义规则命名。
  • 代码结构更清晰

5.总结

  • 约定大于配置,约定我们所有的bean的名字是前缀+订单状态,获取的时候根据订单状态拼接获取Bean处理业务。
  • 注入到组件到Spring管理,实现ApplicationContextAware拿到applicationContext,然后业务需要使用的时候直接根据名称获取组件。
  • 如果是数字的订单状态,我们可以转换为字符串或者利用枚举映射好组件的名称,总之就是约定大于配置(这里约定我们各个状态的组件按照OrderStatusService_加上状态名称)。后续开发状态组件不需要维护if else,只专注开发对应的状态组件
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章