初探策略模式
策略模式:定义了算法族,并分别封装起来,把算法与使用者独立出来,可以在运行时更改类行为或其算法。
场景:假如有一个游戏用户的账号,这个账号有个元宝属性,并且有充值元宝,使用元宝等行为;充值元宝又分为支付宝充值,微信充值,银联卡充值等。
最初的想法是这样的
package pattern.strategy; public class Account { int yuanBao = 0; public void useYuanBao(int use){ yuanBao = yuanBao - use; } public void recharge(String type,int yuanBao){ if(type.equals("支付宝")){ /*-----------------支付宝充值算法--------------------*/ System.out.println("使用支付宝充值"); this.yuanBao = this.yuanBao + yuanBao; }else if(type.equals("微信")){ /*-----------------微信充值算法--------------------*/ System.out.println("使用微信充值"); this.yuanBao = this.yuanBao + yuanBao; }else{ } } }
当前端点击充值的按钮是,传给后端充值类型(type)和元宝数量(yuanBao)并让后端选择充值方式付款。但是这个设计把充值的算法直接写在使用类里面,假如增加一个新的充值方式,那么就要在Account类里面增加代码。当然改善这个代码有很多方式,但是我们来看看策略模式的思想。
第一步,把充值方法抽离出来我们定义一个充值接口
package pattern.strategy; public interface Recharge { public void recharge(); }
并且实现每种充值方式
支付宝:
package pattern.strategy; public class AliPayRecharge implements Recharge { @Override public void recharge() { System.out.println("支付宝充值算法"); } }
微信:
package pattern.strategy; public class WeChatRecharge implements Recharge { @Override public void recharge() { System.out.println("微信充值算法"); } }
第二步,使用类(Account)与算法(Recharge)关联
package pattern.strategy; public class Account { int yuanBao = 0; public void useYuanBao(int use){ yuanBao = yuanBao - use; } public void recharge(Recharge recharge,int yuanBao){ recharge.recharge(); this.yuanBao = this.yuanBao + yuanBao; } }
第三部,选择算法进行充值
package pattern.strategy; public class RechargeController { public static void main(String[] args) { String type = "微信"; int yuanBao = 100; Recharge recharge = null; if(type.equals("微信")){ recharge = new WeChatRecharge(); }else if(type.equals("支付宝")){ recharge = new AliPayRecharge(); } Account account = new Account(); account.recharge(recharge,yuanBao); } }
运行结果:微信充值算法
至此,策略模式已完成代码的改造,策略模式的优势是使用类与算法之间解耦,用户不用关心算法的实现过程,只要结果就行。增加一个新功能不需要修改使用类,便于扩展和维护。如果使用枚举来进行对算法的选择会更佳,这样的话,前端直接传枚举值就能进行算法的选择。
举个更简单的例子,计算器大家都知道吧,我们来封装一下计算器的计算算法。
首先把算法提取出来
package pattern.strategy.cal; public interface Operate { public int operate(int num1,int num2); }
封装加减乘除的算法
package pattern.strategy.cal; public class Add implements Operate { @Override public int operate(int num1, int num2) { return num1 + num2; } }
package pattern.strategy.cal; public class Mul implements Operate { @Override public int operate(int num1, int num2) { return num1 * num2; } }
package pattern.strategy.cal; public class Sub implements Operate { @Override public int operate(int num1, int num2) { return num1 - num2; } }
其次,我们实现一个计算器
package pattern.strategy.cal; public class Cal { private Operate operate; public Cal(Operate operate){ this.operate = operate; } public int execute(int num1,int num2){ return operate.operate(num1,num2); } }
最后我们测试一下这个计算器
package pattern.strategy.cal; public class CalTest { public static void main(String[] args) { System.out.println("1+1="+(new Cal(new Add())).execute(1,1)); System.out.println("1*1="+(new Cal(new Mul())).execute(1,1)); System.out.println("1-1="+(new Cal(new Sub())).execute(1,1)); } }
输出:
1+1=2
1*1=1
1-1=0