利用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,只專注開發對應的狀態組件
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章