以下内容来自我个人的笔记整理,参考了一些非常优秀的博主和开发者的文章,在此表示感谢,本篇博文并非全部原创内容。
这是一种非常常见到的场景,那就是if…else…这种场景
if(type=="A"){
//按照A格式解析
}else if(type=="B"){
//按B格式解析
}else{
//按照默认格式解析
}
这个代码可能会存在哪些问题呢?😶🌫️😶🌫️
如果分支变多,这里的代码就会变得臃肿,难以维护,可读性低。
如果你需要接入一种新的解析类型,那只能在原有代码上修改。
说得专业一点的话,就是以上代码,违背了面向对象编程的开闭原则以及单一原则。
开闭原则(对于扩展是开放的,但是对于修改是封闭的):增加或者删除某个逻辑,都需要修改到原来代码
单一原则(规定一个类应该只有一个发生变化的原因):修改任何类型的分支逻辑代码,都需要改动当前类的代码。
如果你的代码就是酱紫:有多个if…else等条件分支,并且每个条件分支,可以封装起来替换的,我们就可以使用策略模式来优化。
这种代码,说句实在话真的是地狱,特别是在访问量很大的时候,代码效率会被大大降低,那么怎么解决这种情景?那就是本篇博文的主角——策略模式
摘自百度百科🐳🐳
策略模式是指有一定行动内容的相对稳定的策略名称。策略模式在古代中又称“计策”,简称“计”,如《汉书·高帝纪上》:“汉王从其计”。这里的“计”指的就是计谋、策略。策略模式具有相对稳定的形式,如“避实就虚”、“出奇制胜”等。一定的策略模式,既可应用于战略决策,也可应用于战术决策;既可实施于大系统的全局性行动,也可实施于大系统的局部性行动。
策略模式针对一组算法,将每一个算法封装到具有共同接口的独立的类中(在上面的话也就是type A B C …),从而使得它们可以相互替换。
策略模式怎么使用呢?
一个接口或者抽象类,里面两个方法(一个方法匹配类型,一个可替换的逻辑实现方法)
不同策略的差异化实现(就是说,不同策略的实现类)
使用策略模式
定义一个接口
public interface IFileStrategy {
//属于哪种文件解析类型
FileTypeResolveEnum gainFileType();
//封装的公用算法(具体的解析方法)
void resolve(Object objectparam);
}
定义一个枚举类
public enum FileTypeResolveEnum {
File_A_RESOLVE,
File_B_RESOLVE,
File_Default_RESOLVE
}
AFileResolve
public class AFileResolve implements IFileStrategy {
@Override
public FileTypeResolveEnum gainFileType() {
return FileTypeResolveEnum.File_A_RESOLVE;
}
@Override
public void resolve(Object objectparam) {
//A类型解析具体逻辑
System.out.println("A 类型解析文件,参数:"+objectparam);
}
}
BFileResolve
public class BFileResolve implements IFileStrategy {
@Override
public FileTypeResolveEnum gainFileType() {
return FileTypeResolveEnum.File_B_RESOLVE;
}
@Override
public void resolve(Object objectparam) {
//A类型解析具体逻辑
System.out.println("B 类型解析文件,参数:"+objectparam);
}
}
DefaultFileResolve
public class DefaultFileResolve implements IFileStrategy {
@Override
public FileTypeResolveEnum gainFileType() {
return FileTypeResolveEnum.File_Default_RESOLVE;
}
@Override
public void resolve(Object objectparam) {
//A类型解析具体逻辑
System.out.println("Default 类型解析文件,参数:"+objectparam);
}
}
public class TestStrategy {
public static void resolveFile(Map<FileTypeResolveEnum, IFileStrategy> iFileStrategyMap,FileTypeResolveEnum fileTypeResolveEnum, Object objectParam) {
IFileStrategy iFileStrategy = iFileStrategyMap.get(fileTypeResolveEnum);
if (iFileStrategy != null) {
iFileStrategy.resolve(objectParam);
}
}
public static void main(String[] args) {
//形成map集合
Map<FileTypeResolveEnum, IFileStrategy> iFileStrategyMap = new ConcurrentHashMap<>();
iFileStrategyMap.put(FileTypeResolveEnum.File_A_RESOLVE,new AFileResolve());
iFileStrategyMap.put(FileTypeResolveEnum.File_B_RESOLVE,new BFileResolve());
iFileStrategyMap.put(FileTypeResolveEnum.File_Default_RESOLVE,new DefaultFileResolve());
resolveFile(iFileStrategyMap,FileTypeResolveEnum.File_A_RESOLVE,"hi,A!");
}
}