• 策略模式应用(内窥镜项目播放不同种类的视频)


    新旧代码对比

    策略模式

    基本概念

    策略模式是一种行为设计模式,它定义了一系列算法,将每个算法封装起来,并且使它们可以互相替换。策略模式允许客户端选择算法的具体实现,而不必改变客户端的代码。这样,客户端代码就可以根据需要在不同的算法之间切换。

    在你提供的代码中,AnalysisPortCodeStrategy 接口就是一个策略接口,而实现该接口的具体类(可能有多个)就是策略类。每个具体的实现类都代表了一种不同的算法或策略,用于处理特定的业务逻辑。

    在策略模式中,通常有三个角色:

    策略接口(Strategy Interface): 定义一个策略的接口或抽象类,声明了具体策略类需要实现的方法。

    public interface AnalysisPortCodeStrategy {
        List<AnalysisPortCodeInfoBO> getAnalysisPortCodeInfo(GeneralAnalysisQueryParamVO queryParamVO);
        // 其他方法...
    }
    
    • 1
    • 2
    • 3
    • 4

    具体策略类(Concrete Strategies): 实现了策略接口,具体定义了算法的实现。

    public class StrategyA implements AnalysisPortCodeStrategy {
        @Override
        public List<AnalysisPortCodeInfoBO> getAnalysisPortCodeInfo(GeneralAnalysisQueryParamVO queryParamVO) {
            // 具体算法A的实现
            // ...
        }
    }
    
    public class StrategyB implements AnalysisPortCodeStrategy {
        @Override
        public List<AnalysisPortCodeInfoBO> getAnalysisPortCodeInfo(GeneralAnalysisQueryParamVO queryParamVO) {
            // 具体算法B的实现
            // ...
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    上下文类(Context): 包含一个策略接口的引用,可以在运行时切换不同的具体策略。

    public class AnalysisContext {
        private AnalysisPortCodeStrategy strategy;
    
        public AnalysisContext(AnalysisPortCodeStrategy strategy) {
            this.strategy = strategy;
        }
    
        public void setStrategy(AnalysisPortCodeStrategy strategy) {
            this.strategy = strategy;
        }
    
        public List<AnalysisPortCodeInfoBO> executeStrategy(GeneralAnalysisQueryParamVO queryParamVO) {
            return strategy.getAnalysisPortCodeInfo(queryParamVO);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    学习文章:https://zhuanlan.zhihu.com/p/168682592

    优点

    使用策略模式的好处主要在于灵活性和可维护性。下面是一些使用策略模式的优势:

    可扩展性: 策略模式使得你能够轻松地添加新的播放模式,而不必修改主类的代码。如果你要添加新的播放模式,只需创建新的策略类,而不会影响到其他部分的代码。

    可维护性: 每个播放模式都被封装在独立的策略类中,这使得每个策略的逻辑都相对较小,易于理解和维护。这种分离使得修改或调整一个播放模式的行为变得更容易,而不必涉及主类的复杂逻辑。

    解耦合: 主类与具体的播放策略相互解耦合,这意味着它们彼此不直接依赖。这种解耦合有助于保持代码的清晰度,减少代码的复杂性,并使得单独测试每个播放策略变得更容易。

    动态切换: 由于策略是在运行时设置的,你可以动态地切换播放策略,而不需要停止整个应用程序。这对于需要根据不同条件或用户输入改变行为的情况很有用。

    实战改代码

            //如果是2.play 初始化播放,初始化播放模式设置option参数
            //同时修正播放视频名称,将3D模式的上下左右交错全部取左右作为视频源
            if (fileBasicReq.getVideoName().contains("_3DM_TD.mp4")) {
                //上下模式
                if (fileBasicReq.getAction().equals("play")) {
                    fileCplusplusReq.setOption("topDown");
                }
                //实际video都是原视频_3DM_LR.mp4,即07-05-58_3DM_LR.mp4,原视频为左右模式
                realVideoName = fileBasicReq.getVideoName().substring(0, 8) + "_3DM_LR.mp4";
            } else if (fileBasicReq.getVideoName().contains("_3DM_CL.mp4")) {
                //交错模式
                if (fileBasicReq.getAction().equals("play")) {
                    fileCplusplusReq.setOption("cross");
                }
                //实际video都是原视频_3DM_LR.mp4,即07-05-58_3DM_LR.mp4,原视频为左右模式
                realVideoName = fileBasicReq.getVideoName().substring(0, 8) + "_3DM_LR.mp4";
            } else if (fileBasicReq.getVideoName().contains("_3DM_LR.mp4")) {
                //左右模式
                if (fileBasicReq.getAction().equals("play")) {
                    fileCplusplusReq.setOption("leftRight");
                }
            } else if (fileBasicReq.getVideoName().contains("_2DM_LE.mp4") || fileBasicReq.getVideoName().contains("_2DM_RE.mp4")) {
                //2D模式
                if (fileBasicReq.getAction().equals("play")) {
                    fileCplusplusReq.setOption("2d");
                }
            } else {
                log.error("非预期效果");
                throw new BusinessException("找不到对应的播放模式");
            }
    
            fileCplusplusReq.setVideoPath(fileBasicReq.getVideoRootPath().substring(1) + "/" + realVideoName);
           
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    新代码

    
            //如果是2.play 初始化播放,初始化播放模式设置option参数
            //同时修正播放视频名称,将3D模式的上下左右交错全部取左右作为视频源
            // 使用策略
            VideoPlayer videoPlayer = new VideoPlayer();
            if (fileBasicReq.getVideoName().contains("_3DM_TD.mp4")) {
                videoPlayer.setPlayStrategy(new TopDownStrategy());
            } else if (fileBasicReq.getVideoName().contains("_3DM_CL.mp4")) {
                videoPlayer.setPlayStrategy(new CrossStrategy());
            } else if (fileBasicReq.getVideoName().contains("_3DM_LR.mp4")) {
                videoPlayer.setPlayStrategy(new LeftRightStrategy());
            } else if (fileBasicReq.getVideoName().contains("_2DM_LE.mp4") || fileBasicReq.getVideoName().contains("_2DM_RE.mp4")) {
                videoPlayer.setPlayStrategy(new TwoDStrategy());
            } else {
                throw new BusinessException("找不到对应的播放模式");
            }
            if (fileBasicReq.getAction().equals("play")) {
                videoPlayer.playStrategy.apply(fileCplusplusReq, fileBasicReq);
            }
              }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    package com.wg.strategy;
    
    import com.wg.model.FileBasicReq;
    import com.wg.model.FileCplusplusReq;
    
    public interface VideoPlayStrategy {
        void apply(FileCplusplusReq fileCplusplusReq, FileBasicReq fileBasicReq);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    package com.wg.strategy;
    
    public class VideoPlayer {
        public VideoPlayStrategy playStrategy;
    
        public void setPlayStrategy(VideoPlayStrategy playStrategy) {
            this.playStrategy = playStrategy;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    这里只写了其中一种策略

    package com.wg.strategy;
    
    import com.wg.model.FileBasicReq;
    import com.wg.model.FileCplusplusReq;
    
    // 上下模式策略
    public class TopDownStrategy implements VideoPlayStrategy {
        @Override
        public void apply(FileCplusplusReq fileCplusplusReq, FileBasicReq fileBasicReq) {
            fileCplusplusReq.setOption("topDown");
            modifyVideoNameFor3D(fileCplusplusReq, fileBasicReq);
        }
    
        private void modifyVideoNameFor3D(FileCplusplusReq fileCplusplusReq, FileBasicReq fileBasicReq) {
            // 修改视频名称逻辑,例如将"_3DM_TD.mp4"修改为对应的左右模式名称
            fileCplusplusReq.setVideoPath(fileBasicReq.getVideoRootPath().substring(1) + "/" + fileBasicReq.getVideoName().substring(0, 8) + "_3DM_LR.mp4");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
  • 相关阅读:
    17. Series.dt.month-提取日期数据中的月份信息
    蓝牙资讯|AirPods Pro将升级C口充电盒,耳机支持Find My是最大亮点
    代码随想录 - Day34 - 回溯:递增子序列+排列问题
    【深入浅出 Yarn 架构与实现】5-2 Yarn 三种调度器
    Linux性能调优 —— 内存篇
    先获取打印的模板,用户选择过的模板通过接口要回显出来,预览只显示key的值,value是前端写死
    阿里云短信接入 PHP
    docker 容器原理分析笔记(上)
    使用 Bitnami PostgreSQL Docker 镜像快速设置流复制集群
    Spring(二)
  • 原文地址:https://blog.csdn.net/weixin_43914278/article/details/134555923