新舊代碼對比
策略模式
基本概念
策略模式是一種行為設計模式,它定義了一系列算法,將每個算法封裝起來,并且使它們可以互相替換。策略模式允許客戶端選擇算法的具體實現,而不必改變客戶端的代碼。這樣,客戶端代碼就可以根據需要在不同的算法之間切換。
在你提供的代碼中,AnalysisPortCodeStrategy 接口就是一個策略接口,而實現該接口的具體類(可能有多個)就是策略類。每個具體的實現類都代表了一種不同的算法或策略,用于處理特定的業務邏輯。
在策略模式中,通常有三個角色:
策略接口(Strategy Interface): 定義一個策略的接口或抽象類,聲明了具體策略類需要實現的方法。
public interface AnalysisPortCodeStrategy {List<AnalysisPortCodeInfoBO> getAnalysisPortCodeInfo(GeneralAnalysisQueryParamVO queryParamVO);// 其他方法...
}
具體策略類(Concrete Strategies): 實現了策略接口,具體定義了算法的實現。
public class StrategyA implements AnalysisPortCodeStrategy {@Overridepublic List<AnalysisPortCodeInfoBO> getAnalysisPortCodeInfo(GeneralAnalysisQueryParamVO queryParamVO) {// 具體算法A的實現// ...}
}public class StrategyB implements AnalysisPortCodeStrategy {@Overridepublic 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 {@Overridepublic 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");}
}