概念与特点
概念:
模版方法是对封装的一种改造,定义一个抽象类,公共的业务实现放在父类中,需要拓展或者变化的部分放到子类中去完成(即把变化的逻辑增加到子类中,而不改动父类)。最后直接调用模板方法即可。
特点:
- 封装不变部分,拓展可变部分。
- 每个不同的实现都需要定义一个子类,增加子类数目。
- 子类实现父类的方法,会影响父类的结果,导致反向控制。
结构与实现
模板方法模式包含抽象类(模板方法,抽象方法、具体方法、钩子方法),具体子类。
抽象类:由模板方法和若干个基本方法构成。
模板方法:按逻辑顺序调用业务方法。
抽象方法:在抽象类中声明,由具体类实现。
具体方法:在抽象类中实现一些公共的业务场景,子类可以继承或者重写。
钩子方法:在抽象类中已经实现,包括用于判断的逻辑方法和需要子类重写的空方法。
具体子类:实现抽象类中所定义的抽象方法和钩子方法。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>React App</title>
</head>
<body>
<script>
//抽象类-含模板方法,具体方法,钩子方法
class HookAbstract {
templateMethod() {
this.abstractMethod1();
this.hookMethod1();
if (this.hookMethod2()) {
this.specificMethod();
}
this.abstractMethod2();
}
hookMethod1() {
console.log("我是钩子1")
};
hookMethod2() {
return true
}
specificMethod() {
console.log("具体方法被执行...")
}
}
//具体类
class HookConcrete extends HookAbstract {
constructor() {
super();
}
abstractMethod1(){
console.log("抽象方法1被实现")
}
abstractMethod2(){
console.log("抽象方法2被实现")
}
hookMethod1() {
console.log("钩子1被重写")
};
hookMethod2() {
return false
};
}
class Customer {
static main() {
let temp = new HookConcrete();
temp.templateMethod();
}
}
Customer.main();
</script>
</body>
</html>
应用场景
- 实现的业务场景比较固定,只是某些功能点可能需要拓展。
- 多个子类存在公共行为,即可抽离到父类中去实现。
- 需要控制子类的拓展时,模板方法只在特定点调用钩子操作,这样就只允许在这些特定点进行拓展。
应用实例
暂无。
总结
模板方法设计模式可以应用在前端的很多场景。比如封装公共组件,就是将组件作为一种模板。还有 webpack 打包,不断是什么项目,都有一个固定的打包模板。包括 react 的实现。在 react 中作为性能优化的声明周期钩子函数 shouldComponentUpdate 就是在其内部根据 shouldComponentUpdate 的返回值来判断是否重新渲染组件。
【抽象模板】:
1、提供 template 方法,调用具体方法(在抽象类中实现),钩子方法及抽象方法。
【具体模板】:
1、实现抽象模板的抽象方法。