设计模式学习(一):template method
说明:由于本人是一个初学者,所以博客中用到的一些见解、图片、代码或者说明可能引用网络上面的资源,如果涉及到了侵权的问题请大家联系我进行删除。
接下来我们进行第一个设计模式的学习:template method设计模式,也就是模板方法设计模式,之所以把template method设计模式作为设计模式学习的入门,主要有以下几个方面的原因:
- 应用非常广泛
- 比较简单(机制比较简洁,就是虚函数的多态实现)
- 比较好的体现出了设计模式的本质特征(在软件设计流程中关于稳定点和变化点的平衡)
首先我们来看两段程序:
(第一段)
//程序库开发人员
class Library{
public :
void Step1(){
//...
}
void Step3(){
//...
}
void Step5(){
//...
}
};
//应用程序开发人员
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();
}
(第二段)
//程序库开发人员
class Library{
public:
//稳定template method
void Run(){
Step1();
if(Step2()){//支持变化 ==> 虚函数的多态调用
Step3();
}
for(int i = 0; i < 4; i ++){
Step4();//支持变化 ==> 虚函数的多态调用
}
Step5();
}
//C++中基类的虚构函数应该是虚函数,否则在多态中调用析构函数时可能无法调用到子类的析构函数
virtual ~Library(){}
protected:
void Step1(){//稳定
//...
}
void Step3(){//稳定
//...
}
void Step5(){//稳定
//...
}
virtual bool Step2() = 0;//变化
virtual void Step4() = 0;//变化
};
//应用程序开发人员
class Application:public Library{
protected:
virtual bool Step2(){
//...子类实现重写
}
virtual void Step4(){
//...子类实现重写
}
};
int main(){
Library* plib = new Application();
plib ->Run();
delete plib;
}
可以看出,上面的两段程序完成的是同样的功能:就是实现run()方法,并且两段程序中的run()方法实现的内容是一样的,但是两段程序的区别也是比较的明显:
第一段程序 | 第二段程序 |
---|---|
结构化软件设计流程 | 面向对象软件设计流程 |
Library工作人员:开发1,3,5三个步骤 | Library工作人员:开发1,3,5三个步骤,开发程序主流程 |
Application工作人员:开发2,4两个步骤,开发程序主流程 | Application工作人员:开发2,4两个步骤 |
Application调用Library(早绑定) | Library调用Application(通过虚函数向下调用)(晚绑定) |
从程序中我们可以看出:步骤1,3,5和run()方法是稳定的,步骤2,4是变化的。
两段程序的区别在于第一段程序的run()方法由应用程序开发人员进行开发,第二段程序的run()方法由函数库开发人员进行开发。也就是说,第一段程序应用程序开发人员既实现了稳定的部分,也实现了变化的方法,第二段程序对稳定的部分和变化的部分的分工比较明确。
第一段程序实现的是应用程序对函数库的调用,是为早绑定;第二段程序实现的是函数库对应用程序的调用,是为晚绑定,而设计模式的原则之一就是尽量使用晚绑定而不去使用早绑定。
综上所述:从设计模式的角度来看,面向对象软件设计方法优于结构化软件设计方法。
《设计模式》一书中对template method模式的定义如下:
定义一个操作中的算法的骨架(稳定),而将一些操作延迟(变化)到子类中(定义一个虚函数让子类去实现或者说重写这个虚函数),Template Method使得子类可以不改变(复用)一个算法的结构即可重定义(override重写)该算法的某些特定步骤。
设计模式的使用有一个前提条件就是必须要有稳定点,如果没有稳定点的话,那所有的东西都是可以变化的,也就不存在复用的必要了,那么也就没有应用设计模式的必要了。
设计模式最大的作用就是在稳定和变化之间寻找隔离点,然后分离他们,从而管理变化。
说实话,我并没有弄清楚应该怎么样去写明白我学的这一个template method模式,因为我感觉这一个设计模式就是面向对象编程与结构化编程的对比,并没有一定的谁优谁劣。
所以在这一篇博客中我只能尽可能地写出我从这一个设计模式中学到的知识,或者说是我认为比较重要的点,希望能对大家有所帮助。