在Spring中使用策略模式

策略模式是对算法的包装,把使用算法的责任和算法本身分隔开,委派给不同的对象管理。策略模式通常把一系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。

策略模式的一般类图:

纯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的判断从而使代码更容易维护。