設計模式:工廠方法,以及SpringBoot注入整合(附實例)

日常咱們在工做開發過程當中,每每由於工期問題致使總體功能設計考慮的不夠周到,致使後期迭代時發現須要原有功能流程基礎上追加新功能時,須要耗費更多的成本,沒法輕易推翻重構,接着即是將錯就錯,在if else之下再來一層elseif。因此好代碼結構,每每時項目經驗積累出來的,會了不表明能,只有實踐了、實現了,有實際價值體現了,才能發現學習是一點點積累進步的過程。設計模式

而設計模式自己就是經過無數項目積累沉澱而來,適合什麼方式什麼方案去設計實現功能,每每須要全局的分析,考慮到總體,以及將來的可擴展性等等。ide

一、場景分析

工做中其實有不少功能是可使用設計模式的,經過設計模式去優化代碼,達到代碼的複用性,減小耦合,也就是咱們常說的高內聚低耦合。學習

場景1:商城下單

事情是這樣的,小陳接到領導的工做分配,告知要爲負責的商城項目實現下單功能,因而小陳是成竹在胸的實現了,因爲時間問題,小陳並無對功能花時間去作過多設計。便有了如下代碼:優化

@Override
 @Transactional(rollbackFor = ServiceException.class)
 public String createBuyOrders(BuyOrders buyOrders, List<String> couponIds, Long integral, Long integralGym)throws ServiceException{
 productBll.updateSkuStockAndSaleNumber(buyOrders.getBuyOrderProductId(), buyOrders.getBuyOrderSkuId(), buyOrders.getBuyOrderQuantity());
 //訂單基礎信息
 creatOrderBase(buyOrders);
 //計算訂單價格
 normalCalculationOrderPrice(buyOrders);
//完善地址信息
 setOrderAddress(buyOrders);
 //調用優惠券
 couponBll.useCoupons(buyOrders.getBuyOrderUserId(),buyOrders,couponIds);
 if(!IIntegralInfoBll.buyUseIngegral(buyOrders, integral, integralGym)){
 throw new ServiceException("積分扣除失敗,請從新下單");
 }
 if (FavoritesHelper.isNotNull(IBuyOrdersDao.insertBuyOrders(buyOrders))){
 //建立訂單關閉訂單任務
 if (FavoritesHelper.isNotEmpty(systemVariable)){
 closeTime = systemVariable.getSystemVariableVale();
 }
 quartzService.orderTimeout(buyOrders.getBuyOrderNo(),ISystemVariableBll.ORDER_TIME_OVER);
 return buyOrders.getBuyOrderNo();
 }
 throw new RuntimeExcaption("訂單建立失敗");

過了幾周甲方提出了需求,想要實現拼多多那種團購功能,可是由於有優惠了,因此部分優惠券沒法使用。小陳以爲沒什麼壓力,因而對新增了一種訂單類型:團購訂單:

public String createBuyOrders(BuyOrders buyOrders, List<String> couponIds, Long integral, Long integralGym)throws ServiceException{
 if(buyOrders.getType == 1){
 //正常訂單;參考上一段代碼
 } else if( buyOrders.getType == 2 ){
 //團購訂單;具體功能腦部
 //大概實現點:知足設置多少人成爲一個團,參加多久人沒齊會自動取消,拼團過程當中有人退出處理,成功處理,訂單生成未支付鎖定處理
 } else{
 throw new RuntimeException("錯誤的訂單類型");
 }
}

至此,小陳以爲沒啥壓力,也就一個方法幾百行代碼,小問題。debug

又過了幾周,甲方新需求,要有一個秒殺和商品預售功能,小陳頓感壓力,仍是硬着頭皮上了,不就是多幾個if else嗎,還就沒有我小陳ifelseif實現不了的功能了,若是有,就再來一次 else if。設計

因而乎...:指針

public String createBuyOrders(BuyOrders buyOrders, List<String> couponIds, Long integral, Long integralGym)throws ServiceException{
 if(buyOrders.getType == 1){
 //正常訂單;參考上一段代碼
 } else if( buyOrders.getType == 2 ){
 //團購訂單;具體功能腦補
 //大概實現點:知足設置多少人成爲一個團,參加多久人沒齊會自動取消,拼團過程當中有人退出處理,成功處理,訂單生成未支付鎖定處理
 }  else if( buyOrders.getType == 3 ){
 //秒殺訂單;具體功能腦補
 //大概實現點:知足條件商品進行秒殺搶購,流量消峯、庫存控制、訂單生成
 }  else if( buyOrders.getType == 4 ){
 //商品預售訂單;具體功能腦補
 //大概實現點:訂價膨脹,尾款支付提醒
 } else{
 throw new RuntimeException("錯誤的訂單類型");
 }
}

沒等小陳接到甲方的下一個需求,小陳因爲多是我的緣由辭職了,因而新來的阿彬接受了小陳的代碼,碰巧甲方來了新需求:我想來個週期購,增長我商城的復購率...balabala...code

因而阿彬打開先輩的代碼一看,好傢伙,絕了!這東西我怎麼...尚未註釋...orm

二、開始重構

其實向上述的業務情形還有不少,好比與其相對於的商品新增。例如商品填寫完基礎信息以後須要知足商品的週期購售賣邏輯,須要相對於的商品配置邏輯;相對的團購也是,預售商品更爲複雜。咱們能夠一開始就對這些功能進行合理的規劃,而後找出了優化(簡化)的點。就算優化不了,也可將總體的代碼進行合理的設計,不至於維護起來花費太多的成本。對象

下單從新實現:

//1首先:定義下單接口
public interface ICreateOrderBll {
​
    void createOrder(BuyOrders orders);
​
}
​
//2其次:實現下單接口
//2.1秒殺
public class KillSaleOrderBllImpl implements ICreateOrderBll {
     @Override
     public void createOrder(BuyOrders orders) {
    ​
     }
}
​
//2.2普通訂單
public class NormalOrderBllImpl implements ICreateOrderBll {
     @Override
     public void createOrder(BuyOrders orders) {
    ​
     }
}
​
//3預售訂單
public class PreSaleOrderBllImpl implements ICreateOrderBll {
     @Override
     public void createOrder(BuyOrders orders) {
    ​
     }
}
​
//4團購訂單
public class GroupSaleOrderBllImpl implements ICreateOrderBll {
     @Override
     public void createOrder(BuyOrders orders) {
    ​
     }
}
​
//5建立工廠方法的工廠
public class BuyOrderFactory {
​
     public ICreateOrderBll getOrderBll(OrderTypeEnum orderType) throws RuntimeException{
     if (ObjectHelper.isEmpty(orderType)) return null;
     else if (orderType.equals(OrderTypeEnum.NORMAL_ORDER)) return new NormalOrderBllImpl();
     else if (orderType.equals(OrderTypeEnum.KILL_SALE)) return new KillSaleOrderBllImpl();
     else if (orderType.equals(OrderTypeEnum.PRE_SALE)) return new PreSaleOrderBllImpl();
     else if (orderType.equals(OrderTypeEnum.GROUP_SALE)) return new GroupSaleOrderBllImpl();
     else throw new RuntimeException("不存在的訂單類型");
     }
    ​
}
//6備註:其中OrderTypeEnum 是定義的訂單類型枚舉類
​
//7調用
public void createNewOrder(){
     BuyOrders killSaleOrder = new BuyOrders();
    ​
     BuyOrderFactory factory = new BuyOrderFactory();
    ​
     ICreateOrderBll killSaleService = factory.getOrderBll(OrderTypeEnum.KILL_SALE);
     killSaleService.createOrder(killSaleOrder);//秒殺業務
    ​
     BuyOrders preSaleOrder = new BuyOrders();
     ICreateOrderBll preSaleService = factory.getOrderBll(OrderTypeEnum.PRE_SALE);
     preSaleService.createOrder(preSaleOrder);//預售
​
}

自此,下單就重構完成(具體實現根據要求來)。

三、整合SpringBoot

小陳經過學習瞭解了工廠方法,懂得了其中的些許奧祕,但是奈何項目是SpringBoot,只學了皮毛的小陳照虎畫貓,去發現實現的代碼,在代碼執行到具體的業務實現層卻發現空指針,不對啊,不是傳進來的對象都有收到啊,怎麼沒會空指針呢,商品也正常獲取啊,怎麼回事呢?

經過debug,小陳發現是所寫的代碼沒有成功注入SpringBoot中,是對象直接報空指針,因此調用方法是拋出了異常。

因而,小陳悟了:

//重點圈圈1
@Component
public class BuyOrderFactory {
​
     //重點圈圈2
     @Resource
     private Map<OrderTypeEnum,ICreateOrderBll> handlerMap;
    ​
     public ICreateOrderBll getOrderBll(OrderTypeEnum orderType) throws RuntimeException{
     if (ObjectHelper.isEmpty(orderType)) return null;
     else if (orderType.equals(OrderTypeEnum.NORMAL_ORDER)) return new NormalOrderBllImpl();
     else if (orderType.equals(OrderTypeEnum.KILL_SALE)) return new KillSaleOrderBllImpl();
     else if (orderType.equals(OrderTypeEnum.PRE_SALE)) return new PreSaleOrderBllImpl();
     else if (orderType.equals(OrderTypeEnum.GROUP_SALE)) return new GroupSaleOrderBllImpl();
     else throw new RuntimeException("不存在的訂單類型");
     }
​
}
​
//調用
 //重點圈圈3
 @Resource
 BuyOrderFactory factory;
 
 public void createNewOrder(){
     BuyOrders killSaleOrder = new BuyOrders();
    ​
     ICreateOrderBll killSaleService = factory.getOrderBll(OrderTypeEnum.KILL_SALE);
     killSaleService.createOrder(killSaleOrder);//秒殺業務
    ​
     BuyOrders preSaleOrder = new BuyOrders();
     ICreateOrderBll preSaleService = factory.getOrderBll(OrderTypeEnum.PRE_SALE);
     preSaleService.createOrder(preSaleOrder);//預售
​
 }

再後來,小陳由此開始了設計模式學習的不歸路。

相關文章
相關標籤/搜索