标签:接口实现 bsp 耦合 nbsp void 代码 算法 out 必须
策略模式
策略模式是一种软件设计模式,是指对象有某个行为,但是在不同的场合会有不同的实现算法,用编程语言来说,就是说这个类的行为和算法会在运行时作出改变。这种模式属于行为型模式。在我们生活中有这样的例子,比如说商场促销活动,不同的商品有这不同的促销方案八折、五折、生日卡,我们去旅行时,可以选择飞机、火车、大巴等多种出行方案,支付的时候可以选择微信、支付宝、银联等等。
这种场景下,根据用户的需求需要对这个算法作出选择,用户不知道这个算法的具体实现,但是用户知道自己选择哪个算法。
我们以支付为例,先来看看不使用策略模式的代码有什么弊端。
比如说现在有一个购物类,从买东西到下单付款都有一系列的流程,加入东西都买好了,现在要付款了。
/** * 支付类 */ public class PayType { public void payMoney(String type){ if ("支付宝".equals(type)) { System.out.println("支付宝支付,消费200,余额20"); }else if ("微信".equals(type)){ System.out.println("微信支付,消费200,余额10"); }else if ("银联".equals(type)){ System.out.println("银联支付,消费200,余额3000"); } } } /** * 客户端调用 */ public class Strategy { public static void main(String[] args) { PayType payType = new PayType(); String type ="支付宝"; //选择支付宝支付 payType.payMoney(type); } }
我们可以看到,这个支付类有很多if else的判断语句,假如我需要再添加一种支付方式,就需要再次添加一个if 判断,这种方式不但使得支付类语句变得复杂,不易维护,而且也违背了开闭原则。
如果采用策略模式就能够很好的解决这个问题。我们来看下策略模式怎么写。
先看下策略模式的定义:该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。
这里面有几个关键字,具体理解是将每一种算法单独作为一个类,每次新增一个算法就新增一个策略类,修改某个算法不需要修改整个策略类,直接修改对应的算法即可。
策略模式的主要结构如下:
抽象策略类(Strategy):定义一个公共的算法接口,每种算法都实现了这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。
具体策略(Concrete Strategy):实现了这个算法接口的具体实现类。
环境类(Context):持有一个策略类的引用,最终由客户端调用。
策略接口:
/** * 支付接口(策略接口) */ public interface PayType { public void payMoney(); }
具体的策略类:
/** * 微信支付(具体的策略类) */ public class WeiChart implements PayType { @Override public void payMoney() { System.out.println("使用微信支付,付款200元"); } } /** * 支付宝支付(具体的策略类) */ public class Ali implements PayType { @Override public void payMoney() { System.out.println("使用支付宝支付,付款金额200元"); } } /** * 银联卡支付(具体的策略类) */ public class BlankCard implements PayType { @Override public void payMoney() { System.out.println("使用银行卡支付,付款金额200,余额20元"); } }
环境类,上下文对象:
/** * 上下文对象,持有策略类的引用 */ public class Context { PayType payType; public Context(PayType payType) { this.payType = payType; } public PayType getPayType() { return payType; } public void setPayType(PayType payType) { this.payType = payType; } }
客户端调用:
/** * 客户端调用 */ public class Strategy { public static void main(String[] args) { //使用微信支付 Context context1 = new Context(new WeiChart()); context1.getPayType().payMoney(); //使用银联卡支付 Context context2 = new Context(new BlankCard()); context2.getPayType().payMoney(); } } 使用微信支付,付款200元 使用银行卡支付,付款金额200,余额20元
那么,这里有个疑问,为什么不能直接使用接口引用指向具体的实现类,还需要再加一层Context类呢?
我们看下这个类的定义,上下文对象,这个上下文对象是干嘛的,顾名思义,承上启下,上指的是客户端调用类,下指的就是我们这个策略类。
在这里,将实例化具体策略的过程由客户端转到Context类中,客户端只需要和Context类交互即可,使得支付算法和客户端彻底分离,更加降低了客户端和策略类之间的耦合。
看下UML类图:
使用策略模式的优缺点:
优点:
1、能够减少代码的if else逻辑判断,可以在不改变源代码的情况下,新增接口实现类,灵活增加新算法。符合开闭原则。
2、把算法的使用放到环境类中,而算法的实现移到具体策略类中,实现了二者的分离。
缺点:
1、客户端调用类必须明确知道所有算法的区别。
2、每新增一个算法,就需要添加一个策略类。
其实我们发现,策略模式和工厂模式非常相似,但是侧重点不同,策略模式注重的是行为的切换,不是行为的实现。而简单工厂模式注重的是对象的创建。
标签:接口实现 bsp 耦合 nbsp void 代码 算法 out 必须
原文地址:https://www.cnblogs.com/JackSparrow-/p/10733062.html