行为型设计模式:策略模式

策略模式是让策略的实现与策略的使用解耦,在我们日常的开发中,经常用来重构和优化if-else和switch语句。当然,策略模式并不是为了取代if-else和switch语句而生的,这里好多人有一个误区,它的思想是接口的一组实现可以相互替换,让使用和实现解耦。

       策略的使用分为2种,一种是有状态的,每个if-else分支的策略使用都需要new一个新的策略对象;一种是无状态的,每个if-else分支的策略使用都用一个公共的策略对象。

策略类的一个demo如下:

public interface Strategy {
    void doStrategy();
}
​
public class StrategyA implements Strategy {
​
    private Logger logger = LoggerFactory.getLogger(getClass());
​
    public void doStrategy() {
        logger.info("doStrategy StrategyA");
    }
}
​
public class StrategyB implements Strategy{
​
    private Logger logger = LoggerFactory.getLogger(getClass());
​
    public void doStrategy() {
        logger.info("doStrategy StrategyB");
    }
}

 

有状态的策略模式使用:

public class StrategyStatefulFactory {
​
    public static Strategy getStatefulStrategy(String type){
        if (StringUtils.isEmpty(type)){
            throw new IllegalArgumentException("type must be not null");
        }
​
        if(StringUtils.pathEquals(type, "strategyA")){
            return new StrategyA();
        }else if(StringUtils.pathEquals(type, "strategyB")){
            return new StrategyB();
        }else{
            return null;
        }
    }
}

无状态的策略模式使用

public class StrategyNonStatefulFactory {
​
    private static Map<String, Strategy> strategyMap = new HashMap<>(3);
​
    static {
        strategyMap.put("strategyA", new StrategyA());
        strategyMap.put("strategyB", new StrategyB());
    }
​
    public static Strategy getStrategy(String type){
        if (StringUtils.isEmpty(type)){
            throw new IllegalArgumentException("type must be not null");
        }
        return strategyMap.get(type);
    }
}

 

上面的策略工厂,当我们新加入一个策略类时,都需要修改工厂类,这有点不符合开闭原则,那怎么来处理呢?一种方式是在配置文件中增加配置,工厂初始化的时候读配置文件来初始化工厂中map,第二种方式是通过注解来标注策略类,使用java反射机制来初始化工厂中map。这里我给出一个第二种方式实现的demo

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Strategic {
    String value();
}
​
public interface AnnotationStrategy {
    void doStrategy();
}
​
@Strategic(value = "strategyA")
public class AnnotationStrategyA implements AnnotationStrategy{
​
    private Logger logger = LoggerFactory.getLogger(getClass());
​
    public void doStrategy(){
        logger.info("doStrategy AnnotationStrategyA");
    }
}
​
@Strategic(value = "strategyB")
public class AnnotationStrategyB implements AnnotationStrategy{
​
    private Logger logger = LoggerFactory.getLogger(getClass());
​
    public void doStrategy(){
        logger.info("doStrategy AnnotationStrategyB");
    }
}

工厂类代码如下:

public class AnnotationStrategyFactory {

    private static Logger logger = LoggerFactory.getLogger(AnnotationStrategyFactory.class);

    static Map<String, AnnotationStrategy> map = new HashMap<>(3);

    static {
        File classPath = new File("./target/classes/design/behavioral/strategy");
        String clsspath = "design.behavioral.strategy";
        if (classPath.exists()) {
            for (File file : classPath.listFiles()){
                String fileName = file.getName();
                if (fileName.endsWith(".class")) {
                    fileName = fileName.replace(".class", "");
                    try {
                        Class<?> classZ = Class.forName(clsspath + "." + fileName);
                        if (classZ.isAnnotationPresent(Strategic.class)){
                            map.put(classZ.getAnnotation(Strategic.class).value(), (AnnotationStrategy)classZ.newInstance());
                        }
                    } catch (Exception e) {
                        logger.error("exception:", e);
                    }
                }
            }
        }
    }

    public static AnnotationStrategy getAnnotationStrategy(String type) {
        return map.get(type);
    }
}

源码地址:https://github.com/jinjunzhu/design-pattern.git
 

欢迎关注个人微信公众号,共同学习成长

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

君哥聊技术

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值