模式分类
从目的来看
- 创建型(Creational)
- 结构型(Structural)
- 行为型(Behavioral)
从范围来开
- 类模式处理类与子类的静态关系
- 对象模式处理对象间的动态关系
模板方法(Template Method)
“组件协作”模式
框架与应用程序需要拆分,”组件协作“模式通过晚期绑定,来实现框架与应用程序之间的松耦合,是二者协作时常用的模式。
Template Method
动机
在软件构建过程中,对于某一项任务,常常有稳定的整体结构,但各个子步骤却有很多改变的需求,或者由于固有的原因,而无法和任务的整体结构同时实现。
- 如何在确定稳定操作结构的前提下,来灵活应对各个子步骤之间的变化和晚期需求?
早绑定与晚绑定
- 晚开发的应用程序绑定早开发的程序库
- 早开发的程序库绑定晚开发的应用程序
举个栗子
//library.cpp
class library{
void func1(){
...
}
void func3(){
...
}
void func5(){
...
}
}
//main.cpp
class app{
void func2(){
...
}
void func4(){
...
}
}
int main(){
library L;
app A;
if(L.func1())
A.func2();
L.func3();
A.func4();
L.func5();
return 0;
}
在程序库中先开发func1,3,5三个步骤,在application开发时调用lib中的方法,有可能是按顺序执行,也有可能存在某种特定的执行逻辑。以上这种情况就是经典的早绑定。
//library.cpp
class library{
void func1(){
...
}
void func3(){
...
}
void func5(){
...
}
virtual func2() = 0;
virtual func4() = 0;
void func_all(){
if(func1())
func2();
func3();
func4();
func5();
}
virtual ~Library(){}
}
//main.cpp
class app:public library{
void func2(){
...
}
void func4(){
...
}
}
int main(){
app A;
A.func_all();
return 0;
}
在库开发时,将整个流程写好,将后续需要完成的部分写成虚函数,在app中继承lib,只需要在app中写完func2,4即可。这种方式叫做晚绑定。
注意lib的析构函数需要写成虚函数
建议将func2,4这种方法声明成protected方法,因为它们作为单独的方法被其他函数调用意义不大。
模式定义
定义一个操作中的算法的骨架(稳定),而将一些步骤延迟(变化)到子类。模板方法使得子类可以不改变(复用)一个算法的结构即可重定义(override重写)该算法某些特定步骤。
以上是模板模式的基本思想,将稳定的内容写到父类中,变化的内容写到子类实现,从而隔离稳定和变化。
“不要调用我,让我来调用你。”——Template Method