• 优化代码之使用策略模式(解决if..else..问题)


    以下内容来自我个人的笔记整理,参考了一些非常优秀的博主和开发者的文章,在此表示感谢,本篇博文并非全部原创内容。

    优化场景

    这是一种非常常见到的场景,那就是if…else…这种场景

    if(type=="A"){
       //按照A格式解析
     
    }else if(type=="B"){
        //按B格式解析
    }else{
        //按照默认格式解析
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    这个代码可能会存在哪些问题呢?😶‍🌫️😶‍🌫️

    如果分支变多,这里的代码就会变得臃肿,难以维护,可读性低。
    如果你需要接入一种新的解析类型,那只能在原有代码上修改。
    说得专业一点的话,就是以上代码,违背了面向对象编程的开闭原则以及单一原则。

    开闭原则(对于扩展是开放的,但是对于修改是封闭的):增加或者删除某个逻辑,都需要修改到原来代码

    单一原则(规定一个类应该只有一个发生变化的原因):修改任何类型的分支逻辑代码,都需要改动当前类的代码。

    如果你的代码就是酱紫:有多个if…else等条件分支,并且每个条件分支,可以封装起来替换的,我们就可以使用策略模式来优化。

    这种代码,说句实在话真的是地狱,特别是在访问量很大的时候,代码效率会被大大降低,那么怎么解决这种情景?那就是本篇博文的主角——策略模式

    策略模式

    摘自百度百科🐳🐳

    策略模式是指有一定行动内容的相对稳定的策略名称。策略模式在古代中又称“计策”,简称“计”,如《汉书·高帝纪上》:“汉王从其计”。这里的“计”指的就是计谋、策略。策略模式具有相对稳定的形式,如“避实就虚”、“出奇制胜”等。一定的策略模式,既可应用于战略决策,也可应用于战术决策;既可实施于大系统的全局性行动,也可实施于大系统的局部性行动。

    策略模式针对一组算法,将每一个算法封装到具有共同接口的独立的类中(在上面的话也就是type A B C …),从而使得它们可以相互替换。

    实践

    策略模式怎么使用呢?

    一个接口或者抽象类,里面两个方法(一个方法匹配类型,一个可替换的逻辑实现方法)
    不同策略的差异化实现(就是说,不同策略的实现类)
    使用策略模式

    定义一个接口

    public interface IFileStrategy {
        //属于哪种文件解析类型
        FileTypeResolveEnum gainFileType();
    
        //封装的公用算法(具体的解析方法)
        void resolve(Object objectparam);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    定义一个枚举类

    public enum FileTypeResolveEnum {
        File_A_RESOLVE,
        File_B_RESOLVE,
        File_Default_RESOLVE
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    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);
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    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);
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    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);
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    形成Map对象

    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!");
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    在这里插入图片描述

  • 相关阅读:
    boot+mp搭建版本踩坑记录
    grep扩展正则使用
    LEADTOOLS 入门教程: 将注释刻录到图像上的 C# .NET Core 控制台应用程序
    三分钟细数几款可视化前端开发工具
    Spring-依赖注入findAutowireCandidates源码实现
    使用Kettle定时从数据库A刷新数据到数据库B
    分享一个Java毕业设计项目——叮当书城项目
    产品MC动画宣传片制作团队安排
    程序员过不去的坎-算法篇
    测试框架gtest以及内存泄漏检测
  • 原文地址:https://blog.csdn.net/Xmumu_/article/details/127717492