本文介绍23种设计模式的第一种,模板模式,英文是Template Method,这是一个非常常用的设计模式。从封装变化角度来分类,模板模式属于组件协作模式的一种。
定义
定义一个操作中的算法的骨架 (稳定),而将一些步骤延迟 (变化)到子类中。Template Method使得子类可以不改变 (复用)一个算法的结构即可重定义(override 重写)该算法的某些特定步骤。 —《设计模式》 GoF
Motivation 动机
学习设计模式需要知道这个设计模式是用来干嘛的,解决哪一类问题的,这点很关键,但是设计模式的学习又不仅仅只是这些,重点是要学会根据具体的场景找出稳定和不稳定的分界线,在这个分界线处,就是需要使用设计模式的地方。
假设这样的场景,你需要基于framework开发一个APP,这是日常开发中很常用的场景。一般的方法是,厂家提供给你库,你调用库内部的方法写自己的业务,这样毫无疑问是可以的。
但是有一个更加简单的办法,就是厂家在framework把所有的业务流程全部写完,在不确定的位置使用虚函数(C++)或者是函数指针(C语言)代替,而你不需要知道全部的业务范围,只需要把重写虚函数或者实现一个函数指针对应的函数即可,这就是Template Method。
这里面有两个概念,早绑定和晚绑定
- 早绑定:写的晚的代码依赖于写的早的代码,也就是我们日常使用的开发方法
- 晚绑定:写的早的代码依赖于写的晚的代码,也就是我们所说的Template Method模式,framework依赖于app的函数才能正确的运行
代码分析
framework 类
有两个确定的步骤,两个不确定的步骤,和整个业务流程函数
class framework
{
public:
framework();
~framework();
/* 确定的步骤 */
void step1();
void step3();
/* 不确定的步骤 */
virtual void step2();
virtual void step4();
/* 流程 */
void main_loop();
};
framework::framework(){}
framework::~framework(){}
void framework::step1()
{
printf("framework step 1 running ...\n");
}
void framework::step2()
{
printf("framework step 2 running ...\n");
}
void framework::step3()
{
printf("framework tep 3 running ...\n");
}
void framework::step4()
{
printf("framework step 4 running ...\n");
}
void framework::main_loop()
{
step1();
step2();
step3();
step4();
}
两个APP
继承固件库,重写固件库里的虚函数即可
/* 第一个APP */
class App : public framework
{
public:
App();
~App();
void step2();
void step4();
};
App::App()
{
}
App::~App()
{
}
void App::step2()
{
printf("App step 2 running ...\n");
}
void App::step4()
{
printf("App step 4 running ...\n");
}
/* 第二个APP */
class App2 : public framework
{
public:
App2();
~App2();
void step2();
void step4();
};
App2::App2()
{
}
App2::~App2()
{
}
void App2::step2()
{
printf("App2 step 2 running ...\n");
}
void App2::step4()
{
printf("App2 step 4 running ...\n");
}
主函数
int main()
{
printf("=========================\n");
framework *work = new App;
work->main_loop();
printf("=========================\n");
framework *work2 = new App2;
work2->main_loop();
printf("=========================\n");
}
运行结果:
类图
估计很多人尤其新手,在开发应用程序的时候会有种只见树木,不见森林的感觉,就是因为固件库使用了这种设计模式,封装了业务逻辑,而我们只需要重写部分代码即可。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!