持续更新中。。。
在软件构建过程中,对于某一项项目,他常常有稳定的整体结构,(即程序的整体框架是固定的,但是各个函数的实现细节可能会变化或者多个细节的版本)。或者由于固有的原因而无法和任务的整体结构同时实现。那么问题就来了,如何应对这种多个版本的子函数呢?
传统的结构化软件设计流程如下:
//程序库开发人员
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();