模板方法模式,初识时感觉一头雾水,很高大上,现在准备写笔记时仔细一想发现这是最见文生意的一集。
模板:
把大象关进冰箱要几步? 答:打开冰箱门、把大象放进去、关上冰箱门。
课程论文要交了,有没有模板? 答:封面、正文、结尾
不同编程语言代码的执行过程? 答: 保存代码、编译代码、执行代码、输出结果
通过这些例子,发现这确实很“模板”,每个步骤都给抽象了出来,对外只暴露要做什么;但没说怎么做,颇有一种:“模板已经发给你了,你就照着做自己去实现” 的感觉。
引申进代码中,我们这里以不同编程语言代码的执行过程为例:
模板模式
首先写一个提供运行方法的接口
public interface CodeExecute {
/**
* 执行代码
* @param codeContext
*/
void executeCode(CodeContext codeContext);
}
这里定义了CodeContext代码的上下文
public class CodeContext {
/**
* 代码
*/
private String code;
/**
* 编程语言
*/
private String language;
/**
* 输入用例
*/
private String inputList;
}
然后创建代码执行模板(CodeExecuteTemplate)实现CodeExecute 接口,重写executeCode方法,如下,分为4个步骤
public abstract class CodeExecuteTemplate implements CodeExecute{
@Override
public void executeCode(CodeContext codeContext) {
String code = codeContext.getCode();
String inputList = codeContext.getInputList();
//1.保存代码为文件
//2.编译代码
//3.执行代码
//4.整理输出结果,并输出
}
}
然后写对应的方法
public abstract class CodeExecuteTemplate implements CodeExecute{
@Override
public void executeCode(CodeContext codeContext) {
String code = codeContext.getCode();
String inputList = codeContext.getInputList();
//1.保存代码为文件
File codeFile = saveCode(code);
//2.编译代码
compileCode(codeFile);
//3.执行代码
String output = runCode(codeFile,inputList);
//4.整理输出结果,并输出
getoutput(output);
}
public File saveCode(String code) {
System.out.println("正在将代码保存为文件(复用的方法)");
File file = null;
return file;
}
public void compileCode(File codeFile) {
System.out.println("正在编译代码(复用的方法)");
}
public String runCode(File codeFile, String inputList) {
System.out.println("正在运行代码");
/**
* 不同的语言的运行,得到输出output
*/
String output = "****";
return output;
}
public void getoutput(String output) {
System.out.println("输出结果:"+output+"(复用的方法)");
}
}
不同的编程语言这四个步骤都会有差异,这里我们方便起见,只重写第3步执行代码runCode的方法,这样可以认为,cpp和java的4个步骤里只有runCode是不同的,这样就可以只重写runCode,复用其他3个步骤的方法,降低了代码的冗余度
接下来创建CppExecute,JavaExecute,继承模板CodeExecuteTemplate,重写executeCode保证执行步骤1-4,重写runCode方法保证差异性
CppExecute
public class CppExecute extends CodeExecuteTemplate{
@Override
public void executeCode(CodeContext codeContext) {
super.executeCode(codeContext);
}
@Override
public String runCode(File codeFile, String inputList) {
System.out.println("cpp代码运行中");
return super.runCode(codeFile, inputList);
}
}
JavaExecute
public class JavaExecute extends CodeExecuteTemplate{
@Override
public void executeCode(CodeContext codeContext) {
super.executeCode(codeContext);
}
@Override
public String runCode(File codeFile, String inputList) {
System.out.println("java代码运行中");
return super.runCode(codeFile, inputList);
}
}
编写测试用例
class JavaExecuteTest {
@Test
void executeCode() {
CodeContext codeContext = new CodeContext();
codeContext.setCode("java代码");
codeContext.setLanguage("JAVA");
codeContext.setInputList("输入用例");
JavaExecute javaExecute = new JavaExecute();
javaExecute.executeCode(codeContext);
}
}
输出