设计思想:
策略模式的就是定义一系列算法,将他们一个个封装起来,并且使它们可以相互替换,通常我们的代码中出现大量的if...else...或者switch语句时,我们都可以使用策略模式来优化代码
典型场景:
支付系统,拥有多种支付的方式,可以定义不同的支付策略,方便替换。
实践:
在之前的判题服务中,我们对不同语言类型有不同的判题策略,有的语言判题时需要考虑额外的时间或者空间成本,正常我们需要通过if..else来根据语言类型执行不同的判题策略,但是当语言类型过多时,代码很冗余,且不便于扩展,这时我们就可以使用策略模式来进行优化,将不同语言的判题策略封装出去:
定义判题策略接口:
public interface JudgeStrategy {
/**
* 执行判题
* @param judgeContext
* @return
*/
JudgeInfo doJudge(JudgeContext judgeContext);
}
实现各种语言类型的判题策略:
public class DefaultJudgeStrategy implements JudgeStrategy {
/**
* 执行判题
* @param judgeContext
* @return
*/
@Override
public JudgeInfo doJudge(JudgeContext judgeContext) {
JudgeInfo judgeInfo = judgeContext.getJudgeInfo();
// 一系列判题逻辑......
return judgeInfo;
}
}
public class JavaJudgeStrategy implements JudgeStrategy {
/**
* 执行判题
* @param judgeContext
* @return
*/
@Override
public JudgeInfo doJudge(JudgeContext judgeContext) {
JudgeInfo judgeInfo = judgeContext.getJudgeInfo();
// 一系列判题逻辑......
return judgeInfo;
}
}
这样我们就可以在业务代码中根据语言类型去执行各自的判题策略了,但是还是会有if...else,我们可以抽出来一个类去处理选择逻辑,如:
/**
* 判题管理(简化调用)
*/
@Service
public class JudgeManager {
/**
* 执行判题
*
* @param judgeContext
* @return
*/
JudgeInfo doJudge(JudgeContext judgeContext) {
QuestionSubmit questionSubmit = judgeContext.getQuestionSubmit();
String language = questionSubmit.getLanguage();
JudgeStrategy judgeStrategy = new DefaultJudgeStrategy();
if ("java".equals(language)) {
judgeStrategy = new JavaLanguageJudgeStrategy();
}
return judgeStrategy.doJudge(judgeContext);
}
}
这时候业务代码就只需要调用JudgeManager 就行了,不用管是哪种语言。