Template Method
模板方法
template method的方法主要是将实际传统结开发过程的“早绑定“变成面向对象中的“晚绑定”。
比如一个软件栈开发工程中有这两个角色,一个是库功能开发者,一个是解决方案的应用级的程序员。
现在来了一个需求:做一个人脸识别的场景。
那么对于做解决方案的程序员他会先去查看 库程序员提供给他的示例代码,去理解这个过程需要的整个程序的流程。
比如这个程序流程如下
(1)初始化硬件环境
(2)对人脸进行前处理
(3)加载模型
(4)模型输出后处理
(5) 释放硬件资源
这里我们分别叫做step1()~step5();
1、首先库程序员提供step1 step3 step5的实现,其中step2 step4留给解决方案的程序员并提供一个示例程序sample
2、那么解决方案的程序员需要先读懂这个sample程序,然后构建自己的人脸识别的程序。
那么代码结构就是这样的
namespace lib1 {
// 库程序员
return_type step1();
return_type step3();
return_type step5();
}
// 示范程序 smaple
{
step1();
virtual step2();
step3();
virtual step4();
step5();
}
这里我用virtual代表这部分代码是可变的
// 解决方案的程序员
{
step1();
step2();
step3();
step4();
step5();
}
其实我们可以看出解决方案的程序要做的事和sample的代码很相似。但是这段代码对于解决方案的程序员来说“复用性”很差。
当然我这里说的复用不是复制粘贴。而且这对解决方案的程序提出了要求,首先解决方案的程序员需要理解sample代码为代表的整个程序运行的整个流程。
然后才能进行开发。这里面如果有个步骤出错,就需要调整很久,而且当如果库给的接口不是很稳定的时候,说不定解决方案的程序就不能使用了。
这里面的结构就是这样的。
库程序员 |
---|
(1)特定功能的实现 |
(2)示例代码 |
解决方案程序员 |
---|
(1)自己部分定制的代码 |
(2)代码整体结构 |
面向对象的结构
这里将使用到template method方法
类似代码
namespace lib1 {
// 库程序员
class A {
protected:
virtual return_type step2() = 0;
virtual return_type step4() = 0;
private:
return_type step1();
return_type step3();
return_type step5();
public:
virtual ~A();
void Run() {
step1();
// 相应错误处理 ,后面省略
step2();
step3();
step4();
step5();
}
// 示范程序 smaple
{
step1();
virtual step2();
step3();
virtual step4();
step5();
}
// 解决方案的程序员
{
class B : public A{
return_type step2();
return_type step4();
}
A* obj = new B();
obj->Run();
};
}
那么这段代码与上面的程序有什么不同呢。
库程序员 |
---|
(1)特定功能的实现 |
(2)示例代码 |
(3)提供代码结构,对外提供run方法,以及需要解决方案人员实现的部分接口 |
解决方案程序员 |
---|
(1)自己部分定制的代码 (继承于库程序员提供的借口) |
(2)代码整体结构(简单结构) |
上述已经很明白了,库程序员将自己熟悉的流程固定下来, 而将变化的部分让解决方案的程序员来实现。这就让程序从功能上的早绑定变成晚绑定。
这里面的实现的功能就是继续虚函数,继承这些基本功能实现的,其实理解下就知道是基于函数指针实现的。
这样做的优点
- 代码复用性变得更强
- 解决方案的程序员不需要理解库程序员应该理解的整个流程。更加易用。
- 解决方案的程序更好的入门软件库。
- 能够快速的搭建demo
缺点:
1、解决方案的程序员不能完全理解整个流程,只见树不见森林。开发深入后比较困惑和无力。
这样说,可以说是给解决方案提供的是残疾人库。如果解决方案的人需要进一步理解软件栈时,还是需要去阅读类似传统方法的源码。
但是如果都是同级人员,比如说库程序员,也是解决方案的程序员。那么template method将更容易管理代码。
最后说定义
顶定义一个操作算法的骨架(稳定), 而将一些变化的步骤延迟到子类中去。 Tempalte Method使得子类可以不改一个算法的结构实现复用。即是可以override
算法中的特定步骤。
Template Method模式是一种非常基础的设计模式。平时可能在工程中用到,但是没有具体对上号。这个一般是在编写框架的时候回用到,一般框架提供的
拓展点,可能就是基于这个实现的。
“反向控制”,这个也可以理解称为“依赖倒置”。 就是常说的“不要调用我,我来调用你”的话。
注意点
Template Method模式中,父类中变化部分设置为虚函数 或者纯虚函数, 析构函数一定要设成virtual,道理很简单。
变化的部分函数可以设置成为protected。
Run方法中的“动静结合”。