在商城系統中使用設計模式----策略模式之在spring中使用策略模式
阿新 • • 發佈:2019-04-17
這樣的 control actor case imp bean 支付 wire 問題
1.前言:
這是策略模式在spring中的使用,對策略模式不了解對同學可以移步在商城中簡單對使用策略模式。
2.問題:
在策略模式中,我們創建表示各種策略的對象和一個行為,隨著策略對象改變而改變的 context 對象。策略對象改變 context 對象的執行算法。
在spring 中,策略對象在正常情況下是,在啟動Spring容器對時候,已經將策略對象加載創建完成成為bean。
我們如何在Spring中正確對使用策略模式,這樣又會發生什麽問題呢?
3.使用場景:
場景:商城活動中有幾種,滿減,打折,送積分.我們要獲取商品對最終價格。
4.實現
步驟一.創建接口類
public interface GoodsActivity { /** * 獲取應該支付的金額 * @param amount 商品的單價 * @return */ BigDecimal getPayPrice(BigDecimal amount); }
步驟二.實現接口,並添加@Component註解
@Component public class DiscountActivity implements GoodsActivity { //折扣private double discount ; @Override public BigDecimal getPayPrice(BigDecimal amount) { //假裝從數據庫的配置表取折扣 discount = 8.0; return new BigDecimal(discount).multiply(amount).divide(new BigDecimal(10)); } }
@Component public class FullReduceActivity implementsGoodsActivity { //滿多少 private BigDecimal fullAmount; //減多少 private BigDecimal reductionAmount ; @Override public BigDecimal getPayPrice(BigDecimal amount) { //假裝從數據庫的配置表取配置數據 fullAmount = new BigDecimal(300); reductionAmount = new BigDecimal(100); return amount.compareTo(fullAmount)>=0?amount.subtract(reductionAmount):amount; } }
@Component public class IntegralActivity implements GoodsActivity { //抵扣的積分 10積分=1元 private int integral = 100; @Override public BigDecimal getPayPrice(BigDecimal amount) { return amount.subtract(new BigDecimal(integral/10)); } }
步驟三.創建context
public class GoodsActivityContext { private GoodsActivity goodsActivity; public GoodsActivityContext(GoodsActivity goodsActivity){ this.goodsActivity=goodsActivity; } /** * 獲取商品價格 * @param amount * @return */ public BigDecimal getPrice(BigDecimal amount){ return goodsActivity.getPayPrice(amount); } }
步驟四.在控制層中調用策略模式
@RestController public class ActivityController{ @Autowired private DiscountActivity discountActivity; @Autowired private FullReduceActivity fullReduceActivity; @Autowired private IntegralActivity integralActivity; /** * 獲取最終售價 * (這樣的控制層寫法很不友好,需要寫大量的代碼去實現) * 為了解決這個問題,將引用工廠模式... * * 工廠是創建型模式,它的作用就是創建對象; * 策略是行為型模式,它的作用是讓一個對象在許多行為中選擇一種行為; * * 解決不同的問題 * 工廠模式是創建型的設計模式,它接受指令,創建出符合要求的實例;它主要解決的是資源的統一分發,將對象的創建完全獨立出來,讓對象的創建和具體的使用客戶無關。主要應用在多數據庫選擇,類庫文件加載等。 * 策略模式是為了解決的是策略的切換與擴展,更簡潔的說是定義策略族,分別封裝起來,讓他們之間可以相互替換,策略模式讓策略的變化獨立於使用策略的客戶。 * * 工廠相當於黑盒子,策略相當於白盒子; * * * @param activityType * @param amount * @return */ @RequestMapping("getLastPrice") public ResponseResult getLastPrice(String activityType,BigDecimal amount){ ResponseResult responseResult = ResponseResult.getInstance(); GoodsActivityContext goodsActivityContext; //根據活動類型獲取最終售價 switch (activityType){ case "discount": goodsActivityContext = new GoodsActivityContext(discountActivity); break; case "fullReduce": goodsActivityContext = new GoodsActivityContext(fullReduceActivity); break; case "integral": goodsActivityContext = new GoodsActivityContext(integralActivity); break; default: responseResult.setCode(1); responseResult.setMsg("數據類型錯誤"); responseResult.setData(null); return responseResult; } responseResult.setCode(0); responseResult.setMsg("操作成功"); responseResult.setData(goodsActivityContext.getPrice(amount)); return responseResult; } }
總結:按照註釋說明,很明顯我們需要優化這個策略模式。
步驟三:(2) 引入工廠模式,對策略對象進行管理
@Component public class GoodsActivityStrategyFactory { @Autowired private Map<String,GoodsActivity> goodsActivityMap; /** * 根據活動類型 獲取所對應的策略 * @param activityType */ public GoodsActivityContext getGoodsActivityStrategy(String activityType){ GoodsActivityContext goodsActivityContext; switch (activityType){ case "discount": goodsActivityContext = new GoodsActivityContext(goodsActivityMap.get("discountActivity")); break; case "fullReduce": goodsActivityContext = new GoodsActivityContext(goodsActivityMap.get("fullReduceActivity")); break; case "integral": goodsActivityContext = new GoodsActivityContext(goodsActivityMap.get("integralActivity")); break; default: goodsActivityContext = null; } return goodsActivityContext; } }
步驟四.在控制層中調用策略模式
@RestController public class ActivityController{ @Autowired private GoodsActivityStrategyFactory goodsActivityStrategyFactory; @RequestMapping("getLastPrice_V2") public ResponseResult getLastPrice_V2(String activityType,BigDecimal amount){ ResponseResult responseResult = ResponseResult.getInstance(); //從工廠中獲取 活動策略 GoodsActivityContext goodsActivityContext = goodsActivityStrategyFactory.getGoodsActivityStrategy(activityType); if (goodsActivityContext==null){ responseResult.setCode(1); responseResult.setData(null); responseResult.setMsg("數據類型錯誤"); return responseResult; } responseResult.setCode(0); responseResult.setMsg("操作成功"); responseResult.setData(goodsActivityContext.getPrice(amount)); return responseResult; } }
源碼:
在springboot中使用策略模式
在工作中,不能靈活的時候設計模式。希望通過這次的學習,可以加深對設計模式對理解。
接下來會繼續整理出自己在工作對時候可以使用對設計模式,不對望指點。如果文章對您有幫助,github給個start吧。
在商城系統中使用設計模式----策略模式之在spring中使用策略模式