本文介绍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 协议 ,转载请注明出处!

观察者模式 上一篇
线程 下一篇