代码重构: 用实际的例子去讲解模版方法
在很多业务代码中,我们都会遇到这种场景: 如果你把这些逻辑全部写进一个类里,往往会出现: 这正是 模板方法模式 要解决的问题。 一开始,我有一个用于“保存代码文件”的工具类,大概长这样: 当前代码存在不同的报错逻辑: 导致: 整理之后会发现: 不变的部分: 变化的部分: 这正好符合一句模版方法的逻辑: 模板方法模式其实很简单: 父类只做一件事: 这里有三个关键信号: 子类不需要关心: 只管一件事: 当然可以写成这样: 但问题是: 模板方法的好处是: 适合用在: 不适合用在:模板方法模式
一、问题从哪里来?
这个类在不断变大,而且每加一种类型就要改原有代码。二、什么是不变的?
流程固定,具体实现内容待定。
三、模板方法模式的核心想法
把“流程”放在父类,把“变化”交给子类。
规定顺序,不让子类乱来。四、一个简化后的模板类
public abstract class CodeFileSaverTemplate<T> {
public final File saveCode(T result) {
validate(result);
String dir = createDir();
saveFiles(result, dir);
return new File(dir);
}
protected void validate(T result) {}
protected abstract void saveFiles(T result, String dir);
protected String createDir() {
return dir;
}
}saveCode() 是 final:流程不能被改【固定的模版流程】protected:只给子类用abstract:子类必须实现五、子类只关心自己具体实现
HTML 保存
public class HtmlSaver extends CodeFileSaverTemplate<HtmlCodeResult> {
@Override
protected void saveFiles(HtmlCodeResult result, String dir) {
write(dir, "index.html", result.getHtmlCode());
}
}多文件保存
public class MultiFileSaver extends CodeFileSaverTemplate<MultiFileCodeResult> {
@Override
protected void saveFiles(MultiFileCodeResult result, String dir) {
write(dir, "index.html", result.getHtmlCode());
write(dir, "style.css", result.getCssCode());
write(dir, "script.js", result.getJsCode());
}
}
我要写哪些文件。六、为什么不用 if / switch?
if (type == HTML) { ... }
else if (type == MULTI) { ... }新增一种类型 = 新增一个类,不动旧代码。
七、什么时候该用模板方法?