策略模式是对算法的包装,把使用算法的责任和算法本身分隔开,委派给不同的对象管理。策略模式通常把一系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。
策略模式的一般类图:
纯Java实现的策略模式:
1.定义策略接口
package com.bbc.rec.test.other; /** * 话费充值策略<br> * 作者:徐承恩<br> * 日期:2017/1/3-14:51<br> */ public interface PhoneRechargeStrategy { /** * 充值 * @param object 参数 * @return */ public Object doRecharge(Object object); /** * 订单参数 * @param object 参数 * @return */ public Object queryOrder(Object object); }
2.1.实现策略接口
package com.bbc.rec.test.other; /** * 速卡话费充值策略<br> * 作者:徐承恩<br> * 日期:2017/1/3-14:58<br> */ public class EwPayPhoneRechargeStrategy implements PhoneRechargeStrategy { @Override public Object doRecharge(Object object) { System.out.println("调用速卡渠道话费充值接口"); return null; } @Override public Object queryOrder(Object object) { System.out.println("调用速卡渠道订单查询接口"); return null; } }
2.2.实现策略接口
package com.bbc.rec.test.other; /** * 聚合数据话费充值策略<br> * 作者:徐承恩<br> * 日期:2017/1/3-15:01<br> */ public class JuHePhoneRechargeStrategy implements PhoneRechargeStrategy { @Override public Object doRecharge(Object object) { System.out.println("调用聚合数据渠道话费充值接口"); return null; } @Override public Object queryOrder(Object object) { System.out.println("调用聚合数据渠道订单查询接口"); return null; } }
3.策略上下文
package com.bbc.rec.test.other; /** * 话费充值策略上下文<br> * 作者:徐承恩<br> * 日期:2017/1/3-15:04<br> */ public class PhoneRechargeContext { private PhoneRechargeStrategy strategy; public PhoneRechargeContext(PhoneRechargeStrategy strategy) { this.strategy = strategy; } public PhoneRechargeStrategy getStrategy() { return strategy; } }
4.测试代码
package com.bbc.rec.test.other; import org.junit.Test; /** * <br> * 作者:徐承恩<br> * 日期:2016/12/9-14:44<br> */ public class OtherTest { @Test public void t1() { EwPayPhoneRechargeStrategy ewPayPhoneRechargeStrategy = new EwPayPhoneRechargeStrategy(); PhoneRechargeContext context = new PhoneRechargeContext(ewPayPhoneRechargeStrategy); PhoneRechargeStrategy strategy = context.getStrategy(); strategy.doRecharge(null); } }
结合Spring的策略模式
1.改造策略上下文类
package com.bbc.crec.biz.oil; import java.util.HashMap; import java.util.Map; /** * 油卡充值策略工厂<br> * 作者:徐承恩<br> * 日期:2016/12/21-13:24<br> */ public class OilRechargeStrategyFactory { /** * 策略集合 */ private Map<String, OilRechargeStrategy> strategyMap = new HashMap<String, OilRechargeStrategy>(); /** * 设置策略集合<br> * KEY为渠道代号<br> * * @param strategyMap 策略集合 */ public void setStrategyMap(Map<String, OilRechargeStrategy> strategyMap) { this.strategyMap = strategyMap; } /** * 获取策略 * * @param key KEY为渠道代号 * @return OilRechargeStrategy */ public OilRechargeStrategy getStrategy(String key) { return strategyMap.get(key); } }
2.配置Spring XML文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 话费充值渠道策略配置 --> <bean id="phoneRechargeStrategyFactory" class="com.bbc.crec.biz.phone.PhoneRechargeStrategyFactory"> <property name="strategyMap"> <map> <entry key="EWPAY" value-ref="ewPayPhoneRechargeStrategy"/> </map> </property> </bean> <!-- 油卡充值渠道策略配置 --> <bean id="oilRechargeStrategyFactory" class="com.bbc.crec.biz.oil.OilRechargeStrategyFactory"> <property name="strategyMap"> <map> <entry key="EWPAY_OIL" value-ref="ewPayOilRechargeStrategy"/> <entry key="JUHE_OIL" value-ref="juHeOilRechargeStrategy"/> </map> </property> </bean> </beans>
后面具体怎么调用应该很简单了吧,用策略模式的好处是省去了很多的if else的判断从而使代码更容易维护。