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

新旧代码对比

策略模式

基本概念

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

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

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

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

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

具体策略类(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的实现
        // ...
    }
}

上下文类(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);
    }
}

学习文章: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);
       
    }

新代码


        //如果是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);
        }
          }
package com.wg.strategy;

import com.wg.model.FileBasicReq;
import com.wg.model.FileCplusplusReq;

public interface VideoPlayStrategy {
    void apply(FileCplusplusReq fileCplusplusReq, FileBasicReq fileBasicReq);
}
package com.wg.strategy;

public class VideoPlayer {
    public VideoPlayStrategy playStrategy;

    public void setPlayStrategy(VideoPlayStrategy playStrategy) {
        this.playStrategy = playStrategy;
    }
}

这里只写了其中一种策略

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");
    }
}

你可能感兴趣的:(策略模式,音视频)