@pastqing
2015-10-21T11:03:24.000000Z
字数 4388
阅读 3158
java
设计模式
策略模式, 顾名思义就是指对象具有某个行为,但是在不同的业务场景下, 这个行为应该有不同的表现形式, 也就是有了不同的策略。让对象能再不同的场景下对同一行为有不同的实现, 这就是策略模式。
下面是策略模式的类图:
public interface Strategy {
public void algorithmStartegy() ;
}
public class ConcentrateStrategy_1 implements Strategy{
@Override
public void algorithmStartegy() {
System.out.println("I am algorithm strategy 1");
}
}
public class ConcentrateStrategy_2 implements Strategy{
@Override
public void algorithmStartegy() {
System.out.println("I am algorithm strategy 2");
}
}
public class Situation {
Strategy strategy;
public Situation(Strategy strategy) {
this.strategy = strategy;
}
public void handleAlgorithm() {
strategy.algorithmStartegy();
}
}
Situation situation = new Situation(new ConcentrateStrategy_1());
situation.handleAlgorithm();
...
从策略模式的描述以及类图来看真的是非常简单, 总结起来就是策略模式定义了一组算法,它们有一个共同的策略行为接口 ,并且这些算法之间可以互相替换,使算法可以根据场景的不同而改变。
策略模式的应用有很多, 比如说JDK中FilenameFilter的使用过程, 比如场景java.util.Collections.sort(List<T>list, Comparator<? super T>c)
与策略java.util.Comparator
的使用等等。下面我以一个实际的业务场景来具体实现以下策略模式:
1、背景: 中国银行的便民服务包括中国移动手机充值, 中国联通,中国电信。用户选择某个便民服务时, 服务器后台会向银行发送不同的业务XML报文, 已达到通信目的。
2、实现
定义策略接口 : 包含一个生成报文的方法
public interface IProduct {
public String generateXML() ;
}
定义一组具体策略类:
@XMLType("Default")
class DefaultHead implements IProduct {
public String generateXML() {
return "Defalut XML";
}
}
@XMLType("ChinaMobile")
class ChinaMobile implements IProduct{
public String generateXML() {
return "China Mobile XML";
}
}
@XMLType("ChinaUnicom")
class ChinaUnicom implements IProduct {
public String generateXML() {
return "Chinal Unicom XML";
}
}
...
注解先不管, 后文会有解释。
public class XMLGenerator {
private IProduct product = new DefaultHead();
//根据用户缴费类型,生成不同的通信报文
public String generate(String type) {
//注意此处
product = ProductFactory.getInstance().createProduct(type);
return product.generateXML();
}
}
创建具体的策略类, 本来是可以用一系列的if else
判断, 然后new
相应的策略类。这里为了避免if else
我们定义一个策略工厂,来生产具体的策略类。
public class ProductFactory {
// singleton
private ProductFactory() {}
public static ProductFactory getInstance() {
return ProductFactoryInstance.instance;
}
private static class ProductFactoryInstance {
static final ProductFactory instance = new ProductFactory();
}
//创建一个具体的策略类
public IProduct createProduct(String productType) throws URISyntaxException {
// load all startegys
List<Class<? extends IProduct>> startegyList = loadAllStrategy("com.su.startegy");
//遍历所有策略类, 根据条件找出需要用到的
for(Class<? extends IProduct> clazz : startegyList) {
//解析策略类的注解
XMLType xmlType = praseAnnotation(clazz);
if(xmlType.value().equals(productType))
try {
return clazz.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
}
//create IProduct Object failed
return null;
}
//载入策略类方法
private List<Class<? extends IProduct>> loadAllStrategy(String packageName) throws URISyntaxException {
//定义一个策略类的列表
List<Class<? extends IProduct>> strategyList = new ArrayList<Class<? extends IProduct>>();
URI filePath = getClass().getClassLoader().getResource(packageName.replace(".", "/")).toURI();
//获取filepath
File[] files = new File(filePath).listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
if (name.endsWith(".class"))
return true;
return false;
}
});
// load class
for (File file : files) {
try {
Class clazz = getClass().getClassLoader().loadClass(packageName + "." + file.getName().replace(".class", ""));
if (clazz != IProduct.class && IProduct.class.isAssignableFrom(clazz)) {
strategyList.add(clazz);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
return strategyList;
}
//解析注解方法
private XMLType praseAnnotation(Class<? extends IProduct> clazz) {
XMLType xmlType = clazz.getAnnotation(XMLType.class);
if (xmlType == null) {
return null;
}
return xmlType;
}
此处我使用注解的原因是为了简单, 跟代码的耦合紧一点。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface XMLType {
public String value() default "defalut";
}
以上就是此处的策略模式的设计过程,如果需要多种策略的叠加, 也就要相应的使用注解的嵌套了, 这里就不在发挥了。
学习策略模式, 不要记住代码是怎么实现的,更重要的是记住其设计原则。根据原则写代码, 而不是生搬硬套。其实设计模式都是设计原则的体现, 如果理解了设计原则, 那么你写的代码也可以变成一种模式。
1、开闭原则(Open-Closed Principle,缩写为OCP)
2、里氏替换原则(Liskov Substitution Principle,缩写为LSP)
参考文献
策略模式设计原则