背景
在项目中遇到了一个需求,针对外部系统传递过来的参数进行类型校验,在一开始的代码中,我按照往常的习惯,加上注释,一行行地开始编写代码,最后发现了一长串的if-else,很难去维护,也很难弄明白自己写的这段代码是什么鬼。在最近学习了网易云课堂上的设计模式学到了策略模式,自然而然地想起了这个需求,于是乎,开始实操啦~~~
策略模式理解
针对上述需求,我需要遇到string类型的参数时,则自动去匹配调用string类型的校验策略,那么简而言之,策略模式则是提供一个抽象策略供调用方使用,调用方无需知道任何一种具体策略,在需求扩展的情况下,无需改动调用方代码,只需要添加多一个具体策略就能解决需求。这种设计模式属于行为型模式。
看图说话
代码组成
- 抽象策略 ===== TypeValidate
- 具体策略 ===== StringValidate、 NumberValidate
- 调用方 ======= StrategyService
代码实现
抽象策略:
public interface TypeValidate {
public String type();
public boolean typeValidate();
}
具体策略实现抽象策略
@Component
public class StringValidate implements TypeValidate{
@Override
public String type(){
return "string";
}
@Override
public boolean typeValidate(){
System.out.println("this type is string=======");
return true;
}
}
@Component
public class NumberValidate implements TypeValidate{
@Override
public String type(){
return "number";
}
@Override
public boolean typeValidate(){
System.out.println("this type is number=======");
return true;
}
}
调用方:
@Component
public class StrategyService {
private Map<String,TypeValidate> typeValidateMap = new HashMap<>();
public StrategyService(List<TypeValidate> typeValidateList){ //String 特性,默认将TypeValidate的所有实现类都放入到list中
for (int i = 0; i < typeValidateList.size(); i++) {
TypeValidate typeValidate = typeValidateList.get(i);
typeValidateMap.put(typeValidate.type(),typeValidate);
}
}
public void typeValidate(String type){
typeValidateMap.get(type).typeValidate();
}
}
看成果啦~~~
@SpringBootTest(classes = DemoApplication.class) // 需要添加这个注解才可以注入到测试类中,PS:注意要在service中加上注解哦
@RunWith(SpringRunner.class)
public class StrategyTest {
@Autowired
private StrategyService strategyService;
@Test
public void test(){
strategyService.typeValidate("string");
strategyService.typeValidate("number");
}
}
运行结果如下:
需求扩展下:增加多一个类型校验
增加多一个具体策略,调用方代码不变动
@Component
public class EnumValidate implements TypeValidate {
@Override
public String type() {
return "enum";
}
@Override
public boolean typeValidate() {
System.err.println("this type is enum");
return true;
}
}
重新测试下:
@SpringBootTest(classes = DemoApplication.class)
@RunWith(SpringRunner.class)
public class StrategyTest {
@Autowired
private StrategyService strategyService;
@Test
public void test(){
strategyService.typeValidate("string");
strategyService.typeValidate("number");
strategyService.typeValidate("enum");
}
}
测试结果如下:
技能点GET!!!