设计模式-策略模式和工厂模式结合使用
-
怎么把策略模式和工廠模式結合起來使用
如果大家對策略模式和工廠模式不是很了解的話可以先看前面文章
策略模式:https://www.jianshu.com/p/958281936901
工廠模式:https://www.jianshu.com/p/9078481e00c6
大家可能都用過微信支付,在使用微信支付付錢時候:
1、當我們的付款金額大于我們的余額時,會讓我們使用銀行卡支付,
2、余額充足的時候會讓我們優(yōu)先使用余額里面的錢
扣款策略一:
余額(blance) >= 付款金額(tradeAmout) 使用余額
扣款策略二:
余額(blance) < 付款金額(tradeAmout) 使用銀行卡
很明顯這是一個策略模式的實際應用,但是你還記得策略模式的缺陷嗎?它的具體策略必須暴露出去,而且還要由上層模塊初始化,這不適合,與迪米特法則不符( 迪米特法則(Law of Demeter)又叫作最少知識原則(Least Knowledge Principle 簡寫LKP),就是說一個對象應當對其他對象有盡可能少的了解,不和陌生人說話。注:摘自百度百科,這個迪米特法則下次再細講)沖突。高層模塊對底層模塊僅僅在接觸層次上,而不應該是耦合關系。問題出了,我們應該想辦法解決,正好工廠模式可以幫我們解決這個問題。但是引入工廠模式也有問題,工廠方法要指定一個類,它才能生產(chǎn)對象,我們用枚舉來完成。
首先我們先建兩個實體類WxBlance和WxTrade
扣款策略接口
/*** @author shuliangzhao* @Title: Deduction* @ProjectName design-parent* @Description: TODO* @date 2019/5/28 23:53*/ public interface Deduction {public boolean exec(WxBlance wxBlance,WxTrade wxTrade); }扣款策略一
/*** @author shuliangzhao* @Title: BlanceDeduction* @ProjectName design-parent* @Description: TODO* @date 2019/5/28 23:54*/ public class BlanceDeduction implements Deduction {@Overridepublic boolean exec(WxBlance wxBlance, WxTrade wxTrade) {if (wxBlance.getBlance().compareTo(wxTrade.getTradeAmout()) >= 0) {wxTrade.setUserAmout(wxBlance.getBlance());}return true;} }扣款策略二
/*** @author shuliangzhao* @Title: IdCardDeduction* @ProjectName design-parent* @Description: TODO* @date 2019/5/28 23:54*/ public class IdCardDeduction implements Deduction {@Overridepublic boolean exec(WxBlance wxBlance, WxTrade wxTrade) {if (wxBlance.getBlance().compareTo(wxTrade.getTradeAmout()) < 0) {wxTrade.setUserAmout(wxTrade.getTradeAmout());}return true;} }扣款策略封裝
/*** @author shuliangzhao* @Title: DedutionContext* @ProjectName design-parent* @Description: TODO* @date 2019/5/28 23:58*/ public class DedutionContext {private Deduction deduction;public DedutionContext(Deduction deduction) {this.deduction = deduction;}public boolean exec(WxBlance wxBlance,WxTrade wxTrade) {return deduction.exec(wxBlance,wxTrade);} }典型的策略上下文。策略模式的缺陷把所有策略類都暴露出去,怎么修改呢?使用工廠模式根據(jù)映射產(chǎn)生策略對象
策略枚舉
/*** @author shuliangzhao* @Title: StrategyEnum* @ProjectName design-parent* @Description: TODO* @date 2019/5/29 0:00*/ public enum StrategyEnum {BlanceDeduction("com.sl.factorystrategy.BlanceDeduction"),IdCardDeduction("com.sl.factorystrategy.IdCardDeduction");String value = "";private StrategyEnum(String value) {this.value = value;}public String getValue() {return value;} }策略工廠
/*** @author shuliangzhao* @Title: StrategyFactory* @ProjectName design-parent* @Description: TODO* @date 2019/5/29 0:03*/ public class StrategyFactory {public static Deduction getDeduction(StrategyEnum strategyEnum) {Deduction deduction = null;try {deduction = (Deduction)Class.forName(strategyEnum.getValue()).newInstance();} catch (Exception e) {e.printStackTrace();}return deduction;} }扣款調(diào)用類
/*** @author shuliangzhao* @Title: DeductionFacade* @ProjectName design-parent* @Description: TODO* @date 2019/5/29 0:06*/ public class DeductionFacade {//扣款public static void deduct(WxBlance wxBlance,WxTrade wxTrade) {StrategyEnum strate = getStrate(wxBlance, wxTrade);Deduction deduction = StrategyFactory.getDeduction(strate);deduction.exec(wxBlance,wxTrade);}//獲取扣款策略private static StrategyEnum getStrate(WxBlance wxBlance,WxTrade wxTrade) {if (wxBlance.getBlance().compareTo(wxTrade.getTradeAmout()) < 0) {return StrategyEnum.IdCardDeduction;}else {return StrategyEnum.BlanceDeduction;}} }調(diào)用客戶端client
/*** @author shuliangzhao* @Title: Client* @ProjectName design-parent* @Description: TODO* @date 2019/5/29 0:10*/ public class Client {public static void main(String[] args) {WxTrade wxTrade = new WxTrade();wxTrade.setTradeAmout(new BigDecimal("1000"));WxBlance wxBlance = new WxBlance();wxBlance.setBlance(new BigDecimal("999"));DeductionFacade.deduct(wxBlance,wxTrade);System.out.println(wxTrade.getUserAmout());} }執(zhí)行結果
?
image.png
小結:
策略模式:負責對扣款封裝,保證兩個策略自由切換,以后增加策略也很容易
工廠模式:修正策略模式必須對外暴露問題,由工廠模式產(chǎn)生一個具體策略對象
總結
以上是生活随笔為你收集整理的设计模式-策略模式和工厂模式结合使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 设计模式-策略模式(Strategy P
- 下一篇: 设计模式-模板方法(Template M