设计模式-凯发k8官方网
-
怎么把策略模式和工厂模式结合起来使用
如果大家对策略模式和工厂模式不是很了解的话可以先看前面文章
策略模式:https://www.jianshu.com/p/958281936901
工厂模式:https://www.jianshu.com/p/9078481e00c6
大家可能都用过微信支付,在使用微信支付付钱时候:
1、当我们的付款金额大于我们的余额时,会让我们使用银行卡支付,
2、余额充足的时候会让我们优先使用余额里面的钱
扣款策略一:
余额(blance) >= 付款金额(tradeamout) 使用余额
扣款策略二:
余额(blance) < 付款金额(tradeamout) 使用银行卡
很明显这是一个策略模式的实际应用,但是你还记得策略模式的缺陷吗?它的具体策略必须暴露出去,而且还要由上层模块初始化,这不适合,与迪米特法则不符( 迪米特法则(law of demeter)又叫作最少知识原则(least knowledge principle 简写lkp),就是说一个对象应当对其他对象有尽可能少的了解,不和陌生人说话。注:摘自百度百科,这个迪米特法则下次再细讲)冲突。高层模块对底层模块仅仅在接触层次上,而不应该是耦合关系。问题出了,我们应该想办法解决,正好工厂模式可以帮我们解决这个问题。但是引入工厂模式也有问题,工厂方法要指定一个类,它才能生产对象,我们用枚举来完成。
首先我们先建两个实体类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);} }典型的策略上下文。策略模式的缺陷把所有策略类都暴露出去,怎么修改呢?使用工厂模式根据映射产生策略对象
策略枚举
/*** @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;} }扣款调用类
/*** @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;}} }调用客户端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());} }执行结果
image.png
小结:
策略模式:负责对扣款封装,保证两个策略自由切换,以后增加策略也很容易
工厂模式:修正策略模式必须对外暴露问题,由工厂模式产生一个具体策略对象
总结
以上是凯发k8官方网为你收集整理的的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇:
- 下一篇: 设计模式-模板方法(template m