策略模式应用

71 阅读2分钟

场景

我们定义一个动物对象 Animal,自然界中猫,狗等都是动物,但是其各自的行为有不同的形式。如果我们正常的想实现各自的行为,多半会用到 if else,例如:

if(猫){
  System.out.println("输出猫行为");
}
if(狗){
  System.out.println("输出狗行为");
}

但是自然界中的物种是n多的。如果一直 if 下去,可能 if 就能堪比长城了。 这时候策略模式就可以避免这种问题。

策略模式

其实简单的理解策略模式即可,实现的方式是多种的,无需纠结。总体上还是一个if选择。 只是代码中的if else没有了。这种形式 让你的代码可读性也会变高。还是很实用的。

定义 Animal 行为的接口:

public interface StrategyBehaviorSelect<T> {

    /**
     * 获取策略
     */
    StrategyEnums strategy();

    /**
     * 策略的行为
     */
    T behavior(T t);

}

定义路由策略:

public enum StrategyEnums {

    CAT("cat","猫咪行为"),
    DOG("dog","狗狗行为"),

    ;

    /**
     * 策略
     */
    private final String strategy;

    /**
     * 策略简介
     */
    private final String desc;


    StrategyEnums(String strategy, String desc) {
        this.strategy = strategy;
        this.desc = desc;
    }

    public String getStrategy() {
        return strategy;
    }

    public String getDesc() {
        return desc;
    }
}

定义策略工厂:


public class StrategyBehaviorFactory {

    private List<StrategyBehaviorSelect> selects;

    public StrategyBehaviorFactory() {
        selects = new ArrayList<>();
        CatStrategyBehaviorSelect catSelect = new CatStrategyBehaviorSelect();
        DogStrategyBehaviorSelect dogSelect = new DogStrategyBehaviorSelect();
        selects.add(catSelect);
        selects.add(dogSelect);
        this.selects = selects;
    }

    public StrategyBehaviorSelect getSelect(StrategyEnums strategyEnums) {

        if (null == strategyEnums) {
            throw new NullPointerException("策略行为不能为空");
        }

        return selects.stream().filter(item -> Objects.equals(item.strategy(), strategyEnums))
                .findAny().orElseThrow(() -> new NullPointerException("策略行为找不到"));
    }
}

定义猫咪行为:

public class CatStrategyBehaviorSelect implements StrategyBehaviorSelect<String> {


    @Override
    public StrategyEnums strategy() {
        return StrategyEnums.CAT;
    }

    @Override
    public String behavior(String s) {
        return s + "行为:喵喵";
    }
}

定义狗狗行为:

public class DogStrategyBehaviorSelect implements StrategyBehaviorSelect<String> {

    @Override
    public StrategyEnums strategy() {
        return StrategyEnums.DOG;
    }

    @Override
    public String behavior(String s) {
        return s + "行为:汪汪";
    }
}

执行行为:

  //输出结果 = 猫咪行为:喵喵
  public static void main(String[] args){

      //行为工厂
      StrategyBehaviorFactory factory = new StrategyBehaviorFactory();

      //行为选择器
      StrategyBehaviorSelect select = factory.getSelect(StrategyEnums.CAT);

      //猫咪行为
      String result = (String) select.behavior("猫咪");
      System.out.println(result);
  }

}

spring 当中的应用

只需要将具体的行为实现类上注入 @Component 注解,将类交给spring容器进行管理。例如:

猫咪行为

@Component 
public class CatStrategyBehaviorSelect implements StrategyBehaviorSelect<String> {

}

策略工厂改造成:

@Component 
public class StrategyBehaviorFactory {

    @Autowired
    private List<StrategyBehaviorSelect> selects;

    public StrategyBehaviorSelect getSelect(StrategyEnums strategyEnums) {

        if (null == strategyEnums) {
            throw new NullPointerException("策略行为不能为空");
        }

        return selects.stream().filter(item -> Objects.equals(item.strategy(), strategyEnums))
                .findAny().orElseThrow(() -> new NullPointerException("策略行为找不到"));
    }
}

源码浏览地址:github.com/POWERzhangd…