模板模式(Template)
定义一个操作中的算法的骨架,并将一些步骤延迟到子类中,这使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤.
理解
如同我们日常生活中"模板"的意思,做一个标准化的流程,其中一些地方留空,后来者可以根据自己的需要填空.就像试卷,答题的格式已经固定了,你所要做的就是在其中挖空的地方填空,并且每个人填的内容可能都会不一样.
优点
不变部分被封装,使得可变部分可以随意扩展.
缺点
每一个不同的实现都需要一个子类来实现,从而使得类的个数增加.
实现
在一个工作中,总的工作步骤顺序是稳定的,其中某些步骤是变化的.
失败的设计
#include <iostream>
using namespace std;
class TemplateWork {
public:
virtual ~TemplateWork() {}
protected:
void doStep1() { cout << "完成第一项工作" << endl; }
void doStep2() { cout << "完成第二项工作" << endl; }
virtual void run() = 0;
};
class Work1 : public TemplateWork {
public:
void run() {
doStep1();
doStep2();
step3();
step4();
}
private:
void step3() { cout << "完成第三项工作" << endl; }
void step4() { cout << "完成第四项工作" << endl; }
};
class Work2 : public TemplateWork {
public:
void run() {
doStep1();
doStep2();
step3();
step4();
}
private:
void step3() { cout << "完成另一个版本的第三项工作" << endl; }
void step4() { cout << "完成另一个版本的第四项工作" << endl; }
};
int main(void) {
Work1 work1;
work1.run();
cout << endl << endl;
Work2 work2;
work2.run();
system("pause");
return 0;
}
这里失败在哪呢?在于代码的重复,每新增一个版本run()方法就重复一次.
成功的设计
#include <iostream>
using namespace std;
class TemplateWork {
public:
void run() {
doStep1();
doStep2();
step3();
step4();
}
virtual ~TemplateWork(){}
protected:
void doStep1() { cout << "完成第一项工作" << endl; }
void doStep2() { cout << "完成第二项工作" << endl; }
virtual void step3() = 0;
virtual void step4() = 0;
};
class Work1 : public TemplateWork {
void step3() { cout << "完成第三项工作" << endl; }
void step4() { cout << "完成第四项工作" << endl; }
};
class Work2 : public TemplateWork {
void step3() { cout << "完成另一个版本的第三项工作" << endl; }
void step4() { cout << "完成另一个版本的第四项工作" << endl; }
};
int main(void) {
Work1 work1;
work1.run();
cout << endl << endl;
Work2 work2;
work2.run();
system("pause");
return 0;
}
对比失败的设计这里实现了反向调用,调用从父类继承的框架,解决了代码的机械重复问题.