Spring与策略模式
一:策略模式的定义
策略模式是对算法的包装,把使用算法的责任和算法本身分隔开,委派给不同的对象管理。策略模式通常把一系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。
-
模式不是代码,而是某类问题的通用设计解决方案
-
分析项目变化与不变部分,提取变化部分,抽象成接口+实现
-
添加新功能–>父类添加新行为–>所有子类都会继承这个方法
JAVA来实现策略模式,其源代码如下:
// 策略执行
public class Context {
private Strategy stg;
public Context(Strategy theStg) {
this.stg = theStg;
}
public void doAction() {
this.stg.testStrategy();
}
}
//策略接口和实现
public interface Strategy {
void testStrategy();
}
public class PrintStrategy implements Strategy {
public void testStrategy() {
System.out.print("我要打印!!");
}
}
public class WriteStrategy implements Strategy {
public void testStrategy() {
System.out.println("我要写字!!!");
}
}
// 测试 code
public class StrategyClient {
public static void main(String[] args) {
Strategy stgA = new PrintStrategy();
Context ct = new Context(stgA);
ct.doAction();
}
}
二:spring实现策略模式
现在使用spring的系统可以说是多如牛毛,那么如何在spring模式下实现策略呢?
其实只需要稍微改造下就可以了,因为spring的核心之一就是IOC。
首先修改Contex类:
public class ContextSpring {
private Strategy stg;
/**
* Setter method for property <tt>stg</tt>.
*
* @param stg value to be assigned to property stg
*/
public void setStg(Strategy stg) {
this.stg = stg;
}
public void doAction() {
this.stg.testStrategy();
}
}
然后在spring配置文件里面配置,
<bean id="ct" class = "com.proxy.strategy.ContextSpring">
<property name="stg" ref="writeStg"/>
</bean>
<bean id="writeStg" class = "com.proxy.strategy.impl.WriteStrategy"/>
<bean id="printStg" class = "com.proxy.strategy.impl.PrintStrategy"/>
里面选择你将要注入的实现类,然后在执行的代码里面写这样:
public class StrategySpringClient {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
ContextSpring ct = (ContextSpring) context.getBean("ct");
ct.doAction();
}
}
看,这样就将spring引入了。
但是这样有好处也有坏处,如果我要根据不同的类型,比如说:合同是需要打印的,而情书是需要手写的。假设合同为类型2,情书为类型1,那我们怎么来自动适配?
三:高级版的spring策略模式
首先要修改Context类:
public class ContextSpringFactory {
private Map<String, Strategy> stgMap = new HashMap<String, Strategy>();
/**
* Getter method for property <tt>stgMap</tt>.
*
* @return property value of stgMap
*/
public Map<String, Strategy> getStgMap() {
return stgMap;
}
/**
* Setter method for property <tt>stgMap</tt>.
*
* @param stgMap value to be assigned to property stgMap
*/
public void setStgMap(Map<String, Strategy> stgMap) {
this.stgMap = stgMap;
}
public void doAction(String strType) {
this.stgMap.get(strType).testStrategy();
}
}
然后修改spring的配置文件:
<bean id="ctf" class = "com.proxy.strategy.ContextSpringFactory">
<property name="stgMap">
<map>
<entry key="1" value-ref="writeStg"/>
<entry key="2" value-ref="printStg"/>
</map>
</property>
</bean>
<bean id="writeStg" class = "com.proxy.strategy.impl.WriteStrategy"/>
<bean id="printStg" class = "com.proxy.strategy.impl.PrintStrategy"/>
执行的入口类修改为:
public class StrategySpringClientFactory {
public static void main(String[] args) {
//外部参数
String type = "1";
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
ContextSpringFactory ctf = (ContextSpringFactory) context.getBean("ctf");
ctf.doAction(type);
//type 2
type = "2";
ctf.doAction(type);
}
}