美文网首页
行为型 策略模式(下)(Type的选择)(文末有项目连接)

行为型 策略模式(下)(Type的选择)(文末有项目连接)

作者: _River_ | 来源:发表于2021-05-03 21:49 被阅读0次
1:策略模式的问题
假如策略是无状态的    
1:策略创建的时候可以使用Map来缓存无状态的对象(已解决)
2:但是在进入策略前 假如入参type还没有确定 还是需要使用if-else 来获取type(未解决)
                                                    
假如策略是有状态的 
1:策略创建的时候就需要大量的if-else 来判断创建哪个策略对象(未解决)
2:同时在进入策略前 假如入参type还没有确定 还是需要使用if-else 来获取type(未解决)
                            
那么实际上还有一个很严重的问题 如何避免 if-else来获取type呢
2:如何避免 if -else(策略创建)
一个很好的选择方法就是通过枚举 

假如 现在策略创建的对象是有状态  如何避免大量的if-else来创建对象
public class StrategyFactoryStateEnum {

    public static Strategy getStrategy(String type) {
        if (type == null || type.isEmpty()) {
            throw new IllegalArgumentException("type should not be empty.");
        }

        //使用枚举获取对象
        return StrategyEnum.getStrategyeByName(type);
    }
}
public enum StrategyEnum {

    ConcreteStrategyA("ConcreteStrategyA",new ConcreteStrategyA()),
    ConcreteStrategyB("ConcreteStrategyB",new ConcreteStrategyB());

    private String name;

    private Strategy strategy;

    StrategyEnum(String name , Strategy strategy){
        this.name = name;
        this.strategy = strategy;
    }

    public String getName() {
    return name;
    }

    public Strategy getStrategy() {
      return strategy;
    }

    //根据名称遍历 获取对应的对象
    public static Strategy getStrategyeByName(String name){
    if (StringUtils.isEmpty(name)){
        return null;
     }
    for (StrategyEnum strategyEnum : StrategyEnum.values()) {
        if (name.equals(strategyEnum.getName())){
            return strategyEnum.getStrategy();
        }
    }
    return null;
    }
}
突然发现使用枚举的方式  和 在无状态策略  中Map根据key值获取value的方式非常像
那么能否使用无状态策略中的Map来获取对应的对象呢

稍微做修改即可  使用深拷贝的方法获取复制出一个该type对应的对象
public class StrategyFactoryStatelessEnum {

    private static final Map<String, Strategy> strategies = new HashMap<>();

    static {
        strategies.put("ConcreteStrategyA", new ConcreteStrategyA());
        strategies.put("ConcreteStrategyB", new ConcreteStrategyB());
    }

    public static Strategy getStrategy(String type) {
        if (type == null || type.isEmpty()) {
            throw new IllegalArgumentException("type should not be empty.");
        }
        //使用JSONObject进行深拷贝
        Strategy strategy = JSONObject.parseObject(JSONObject.toJSONString(strategies.get(type)), Strategy.class);
        return strategy;
    }
}
3: 如何避免 if -else(策略使用)
现在策略的创建 不管是无状态 还是有状态 都可以通过 Map或者枚举的方式来获取 type对应的对象

那么在使用策略 如何避免if-else 来获取对应的type呢

实际上也是同样的可以用枚举的方式获取Tpye
在上述的StrategyFactoryStateEnum中
我们既然可以根据相应的Type获取相应的对象
那么实际上我们也可以同样 使用相同的逻辑获取相应的Type

最终在代码主逻辑可能会传入  Int Long  String 等类型的值   使用枚举获取对应的Type即可
public enum  StrategyTypeEnum {

    ConcreteStrategyTypeA("ConcreteStrategyNameA","ConcreteStrategyA"),
    ConcreteStrategyTypeB("ConcreteStrategyNameB","ConcreteStrategyB");

    private String name;

    private String strategyType;

    StrategyTypeEnum(String name , String strategyType){
        this.name = name;
        this.strategyType = strategyType;
    }

    public String getName() {
        return name;
    }

    public String getStrategyType() {
        return strategyType;
    }

    //根据名称遍历 获取对应的对象
    public static String getStrategyeByName(String name){
        if (StringUtils.isEmpty(name)){
            return null;
        }
        for (StrategyTypeEnum strategyTypeEnum : StrategyTypeEnum.values()) {
            if (name.equals(strategyTypeEnum.getName())){
                return strategyTypeEnum.getStrategyType();
            }
        }
        return null;
    }
}
4: 策略模式 总结
1:使用策略时  不管是 策略对象是有状态还是无状态 都可以使用枚举获取传入的Type

2:在创建策略时 
    策略对象是无状态:可以把对象新建到 Map集合中  根据传入的Tpye 获取对象
    
    策略对象是有状态:
                        1:可以把对象新建到 Map集合中,根据传入的Tpye 获取对象
                            然后使用JsonObject复制策略对象返回
                        2:使用枚举 根据传入的Type获取对象

策略模式与工厂模式对比
策略模式  注重 策略的选择
工厂模式  注重 对象的创建

策略模式 :策略的创建由工厂类(非真正意义的工厂)来完成,封装策略创建的细节。
工厂模式 :工厂创建对象时,由于内部工厂都是重新创建对象,而外部工厂是无状态的。
             理解为两个工厂:外部工厂  创建  创建对象的内部工厂
             因此可以使用策略思维,使用Map存放无状态的外部工厂。

项目连接

请配合项目代码食用效果更佳:
项目地址:
https://github.com/hesuijin/hesujin-design-pattern
Git下载地址:
https://github.com.cnpmjs.org/hesuijin/hesujin-design-pattern.git

demo-study模块  下 behavior_design_pattern  strategy包     

相关文章

网友评论

      本文标题:行为型 策略模式(下)(Type的选择)(文末有项目连接)

      本文链接:https://www.haomeiwen.com/subject/jfjqdltx.html