场景
我们定义一个动物对象 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…