本文已参与「新人创作礼」活动,一起开启掘金创作之路。
1.策略模式定义:
策略模式定义了接口和不同的实现类,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的的客户。
这个策略模式的定义是不是有点抽象呢?那我们来看点通俗易懂的比喻:
比喻1:我们打农药的时候,不同的英雄都有不同的大招。假如我们释放一技能,怎么操作?根据英雄的类型,在不同的时机释放大招。
比喻2:假设你跟不同性格类型的小姐姐约会,要用不同的策略,有的请电影比较好,有的则去吃小吃效果不错,有的去逛街买买买最合适。当然,目的都是为了得到小姐姐的芳心,请看电影、吃小吃、逛街就是不同的策略。
策略模式针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。
2.策略模式的使用场景
2.1 逆推法,策略模式被前辈们总结出来,解决的主要问题?
当程序中出现一堆连在一起的if…else语句,例如:
public void t(){
...
if(a){
...
}else if(b){
...
}else if(c){
...
}else{
...
}
...
}
此时对于这一对if…else语句,每个条件a,b,c…可能会很复杂,维护起来也很难,尤其后续新增加不同情况的操作,还需要新增加if…else,耦合度太高。
2.2 面试是实战中的逻辑图:
不同会员打折
不同角色领导审批
3.实战demo
3.1策略接口
public interface IFileStrategy {
//属于哪种文件解析类型
FileTypeResolveEnum gainFileType();
//封装的公用算法(具体的解析方法)
void resolve(Object objectparam);
}
3.2 A 类型策略具体实现
@Component
public class AFileResolve implements IFileStrategy {
@Override
public FileTypeResolveEnum gainFileType() {
return FileTypeResolveEnum.File_A_RESOLVE;
}
@Override
public void resolve(Object objectparam) {
System.out.println("*******************执行A的逻辑************");
//A类型解析具体逻辑
}
}
3.3 B 类型策略具体实现
@Component
public class BFileResolve implements IFileStrategy {
@Override
public FileTypeResolveEnum gainFileType() {
return FileTypeResolveEnum.File_B_RESOLVE;
}
@Override
public void resolve(Object objectparam) {
System.out.println("*******************执行B的逻辑************");
//B类型解析具体逻辑
}
}
3.4 默认类型策略具体实现
@Component
public class DefaultFileResolve implements IFileStrategy {
@Override
public FileTypeResolveEnum gainFileType() {
return FileTypeResolveEnum.File_DEFAULT_RESOLVE;
}
@Override
public void resolve(Object objectparam) {
System.out.println("*******************执行默认的逻辑************");
//默认类型解析具体逻辑
}
}
3.5 不同角色的枚举
public enum FileTypeResolveEnum {
File_A_RESOLVE(10,"1111"),
File_DEFAULT_RESOLVE(20,"2222"),
File_B_RESOLVE(30,"3333");
private Integer code;
private String value;
FileTypeResolveEnum(Integer code, String value) {
this.code = code;
this.value = value;
}
public static FileTypeResolveEnum getEnumByCode(Integer code) {
for (FileTypeResolveEnum requireOrderUnitProcessEnum : FileTypeResolveEnum.values()) {
if (requireOrderUnitProcessEnum.getCode().equals(code)) {
return requireOrderUnitProcessEnum;
}
}
return null;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
3.6 service层
@Autowired
private List<IFileStrategy> iFileStrategies;
private Map<FileTypeResolveEnum, IFileStrategy> handlerMap;
@PostConstruct
public void init() {
handlerMap = iFileStrategies.stream().collect(Collectors.toMap(IFileStrategy::gainFileType, handle -> handle));
}
/****************不同角色调用同一个方法,执行不同的业务**********/
public void contextLoads(@RequestBody StrategyReq strategyReq) {
handlerMap.get(strategyReq.getFileTypeResolveEnum()));
}
}
@Data
public class StrategyReq {
private FileTypeResolveEnum fileTypeResolveEnum;
}
CV到数据库,跑不出来,你找我。(公司的逻辑代码都删了,这是一个通用的架子)
4.策略模式优缺点
4.1优点
1.符合开闭原则,增加策略只需要增加具体策略实现类即可
2.减少了if和else的使用,,便于后期的扩展和维护
开闭原则(对于扩展是开放的,但是对于修改是封闭的):增加或者删除某个逻辑,都需要修改到原来代码
单一原则(规定一个类应该只有一个发生变化的原因):修改任何类型的分支逻辑代码,都需要改动当前类的代码。
4.2缺点
1.客户端需要知道使用哪种具体策略(对不同的女性采取不同的策略)
2.策略模式会产生很多策略类,多后期学习维护增加一定难度
CSDN链接:blog.csdn.net/guoqi_666/a…