在开发中,有时候实现一个功能有多种方法或者说是策略,在实现的过程中可以根据条件来进行选择不同的方法或者策略,比如对一个集合进行排序,可以根据客户端传进来的条件来选择不同的排序算法,如冒泡排序,堆排序,快速排序......等。
对于这种需求,一般的解决办法就是在一个方法中 通过 if....else if....else 或者 switch case 来解决,这样有一点不好的地方,如果我们要添加一个新的算法,或者删除一个已有的算法,则必须要修改源代码来实现,去掉/添加一个 else 分支或者 case分支,代码的扩展性和维护性较差,对于这种需求的话,可以使用策略模式来进行解决。
策略模式 :
定义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换。
下面以一个网购付款方式为例进行说明:
在网购付款的时候,可以选择的付款方式有很多种,如支付宝,微信,信用卡和 ApplePay等。
首先定义抽象策略类PayWay:
public abstract class PayWay { public abstract boolean pay(double money); }
定义具体策略类:
支付宝支付类:
/** * 支付宝支付 * @author Administrator * */public class AlPay extends PayWay{ @Override public boolean pay(double money) { System.out.println(String.format("使用支付宝成功付款:%f", money)); return true; }}
微信支付类:
/** * 微信支付 * @author Administrator * */public class WeChatPay extends PayWay{ @Override public boolean pay(double money) { System.out.println(String.format("使用微信成功付款:%f", money)); return true; }}
信用卡支付类:
/** * 信用卡支付 * @author Administrator * */public class CreditCardPay extends PayWay{ @Override public boolean pay(double money) { System.out.println(String.format("使用信用卡成功付款:%f", money)); return true; }}
客户端类
在客户端类中,只需持有抽象策略类的一个引用。
class Client{ private PayWay payWay = null; public void setPayWay(PayWay payWay) { this.payWay = payWay; } public void pay(double money){ payWay.pay(money); }}
测试:
public static void main(String[] args) { Client client = new Client(); // 支付宝 client.setPayWay(new AlPay()); client.pay(1000); //微信 client.setPayWay(new WeChatPay()); client.pay(1000); //信用卡 client.setPayWay(new CreditCardPay()); client.pay(1000); }
结果:
使用支付宝成功付款:1000.000000使用微信成功付款:1000.000000使用信用卡成功付款:1000.000000
现在如果想添加一种新的付款方式,ApplePay,只需新加一个类,继承抽象策略类即可,
ApplePay类:
/** * ApplePay支付 * @author Administrator * */public class ApplePay extends PayWay{ @Override public boolean pay(double money) { System.out.println(String.format("使用苹果成功付款:%f", money)); return true; }}
可以看到,新添加一个策略或者算法,对原来的代码没有改动,只是新加了一个类而已,如果想不使用某个算法或策略,如不想使用信用卡支付,则在客户端进行调用的时候,不传入 CreditCardPay对象即可,对原来的代码也没有改动,由此可以看到维护性和扩展性较高。
缺点:
策略模式也有它的缺点,如客户端在进行调用的时候,必须知道每个算法或者策略的不同;如果策略很多,则会有很多的具体策略类,造成大量的类。