背景
在软件构建过程中,某一项目可能有以下特征:
- 代码结构固定,函数流程固定,但各个接口的实现有多个版本;
- 由于某种原因整体结构和各接口无法同时实现。同时又要应对多个子版本
传统的结构化软件设计流程如下:
//程序库开发人员
class Library{
public:
void Step1(){
//...
}
void Step3(){
//...
}
void Step5(){
//...
}
};
//应用程序开发人员
#include "templte1_lib.h"
class Application{
public:
bool Step2(){
//...
}
void Step4(){
//...
}
};
int main()
{
Library lib();
Application app();
lib.Step1();
if (app.Step2()){
lib.Step3();
}
for (int i = 0; i < 4; i++){
app.Step4();
}
lib.Step5();
}
上述为类似于伪代码,没有完整实现,
(1)程序库开发人员开发1、3、5三个步骤
(2)Applocation开发人员开发2、4、两个步骤和程序主流程
如果我们步骤2、4还有两个实现版本,暂且设为7、8、;那么我们不仅要写出7、8两个子函数,而且要重写程序主框架,将Step2()和Step4()更换为Step7()和Step8(),这就不符合我们设计模式的原则,开放扩展,关闭更改。
我们设想是既然程序框架不变,我们可以在库开发时就设计程序主流程
//程序库开发人员
class Library{
public:
//稳定 template method
void Run(){
Step1();
if (Step2()) { //支持变化 ==> 虚函数的多态调用
Step3();
}
for (int i = 0; i < 4; i++){
Step4(); //支持变化 ==> 虚函数的多态调用
}
Step5();
}
virtual ~Library(){ }
protected:
void Step1() { //稳定
//.....
}
void Step3() {//稳定
//.....
}
void Step5() { //稳定
//.....
}
virtual bool Step2() = 0;//变化
virtual void Step4() =0; //变化
};
(1)程序库开发人员开发步骤稳定的1、3、5步骤和整体框架void run();并将会变化的2、4设计为虚函数供后续实现;
应用程序开发人员所做的工作如下:
//应用程序开发人员
class Application : public Library {
protected:
virtual bool Step2(){
//... 子类重写实现
}
virtual void Step4() {
//... 子类重写实现
}
};
int main(){
Library* pLib=new Application();
pLib->Run();
delete pLib;
return 0;
}
继承Library,并实现其中的虚函数步骤2、4;
在main函数中,父类指针指向子类对象,调用pLib->Run()时会调用子类的函数实现。
变化的时候到了
当步骤2、4更改时,我们只需新建一个类Application2,同样继承自Library,重写步骤2、4
main函数中实现就是:
int main(){
Library *pLib=new Application2();
pLib->Run();
delete pLib;
return 0;
}
pLib会根据指向对象去多态调用Step2和Step4();
总结
所谓模板方法,就是将一些容易变化的函数接口的实现交给各个业务去实现。
本文深入探讨了模板方法设计模式的实现原理与应用,通过对比传统软件设计流程,阐述了如何利用虚函数和多态调用,实现稳定框架与可变细节的分离,从而达到开放扩展、关闭更改的设计原则。
1778

被折叠的 条评论
为什么被折叠?



