一、定义
百度百科给的定义:定义一个操作中的算法骨架(稳定),而将一些步骤延迟到子类中(变化)。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(); }
app.Step5(); }
很简单的代码,这段代码不一定是分开两个人来写,也有可能是同一个写或多个人来写,这里无所谓。
一般来说,程序库开发人员的代码写的比较早,这些代码是稳定的,不会进行改变的。而应用程序开发人员的代码写的比较晚,这些代码是随需求变化而变化的。
一般来说,算法主体代码也是稳定的,不会变的。但如果由应用程序开发人员来写,一,他需要懂这个算法具体如何实现,且能正确的写出来;二,如果多个地方用到了这个算法,岂不是要写这个算法很多次?代码复用率低。
然后我们来看下使用模板方法后的代码:
//程序库开发人员 class Library { public: 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; //变化 } //应用程序开发人员 class Application { public: virtual bool Step2(){ //子类重实现变化部分 } virtual void Step4(){ //子类重实现变化部分 } } int main() { Library* lib = new Application(); lib.Run(); delete lib; }
使用了模板方法后,算法的实现是由程序库开发人员写的,他可以保证算法的正确性。后续想用此算法的人,只需根据需求重写一下变化部分,即可轻松调用,代码的复用性和准确性得到了保证。
参考视频:https://www.bilibili.com/video/av22292899/?p=3(PS: B站真是一个学习的好地方>_<!)