模板方法模式
定义一个操作中的算法的骨架,而将一些步骤延迟到子类。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
-
主要解决:一些方法通用,却在每一个子类都重新写了这一方法。
-
如何解决:将这些通用算法抽象出来。
-
关键代码:在抽象类实现,其他步骤在子类实现。
-
应用实例: 1、在造房子的时候,地基、走线、水管都一样,只有在建筑的后期才有加壁橱加栅栏等差异。 2、西游记里面菩萨定好的 81 难,这就是一个顶层的逻辑骨架。 3、spring 中对 Hibernate 的支持,将一些已经定好的方法封装起来,比如开启事务、获取 Session、关闭 Session 等,程序员不重复写那些已经规范好的代码,直接丢一个实体就可以保存。
-
优点: 1、封装不变部分,扩展可变部分。 2、提取公共代码,便于维护。 3、行为由父类控制,子类实现。
-
缺点:每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。
-
使用场景: 1、有多个子类共有的方法,且逻辑相同。 2、重要的、复杂的方法,可以考虑作为模板方法。
AbstractClass类
抽象类,定义并实现了一个模板方法,这个模板方法一般是具体方法,它给出了一个顶级逻辑框架,而逻辑的组成是由相应的抽象操作,它们推迟到子类去实现。顶级逻辑也可能调用一些具体方法。
ConcreteClass类
实现父类定义的一或多个抽象方法,每一个AbstractClass都可以有任意多ConcreteClass与之对应,而每个ConcreteClass都可以给出这些抽象方法(也就是顶级逻辑的组成步骤)的不同实现,从而使得顶级逻辑的实现各不相同。
#include <iostream>
using namespace std;
class AbstractClass {
public:
//一些抽象行为可以放到子类去实现
virtual void PrimitiveOperation1(){}
virtual void PrimitiveOperation2(){}
//模板方法
void TemplateMethod(){
PrimitiveOperation1();
PrimitiveOperation2();
}
};
class ConcreteClassA: public AbstractClass{
public:
virtual void PrimitiveOperation1(){cout << "具体类A方法1实现" << endl;}
virtual void PrimitiveOperation2(){cout << "具体类A方法2实现" << endl;}
};
class ConcreteClassB: public AbstractClass{
public:
virtual void PrimitiveOperation1(){cout << "具体类A方法1实现" << endl;}
virtual void PrimitiveOperation2(){cout << "具体类A方法2实现" << endl;}
};
客户端调用
int main(){
AbstractClass* C;
C = new ConcreteClassA;
C->TemplateMethod();
delete C;
C = new ConcreteClassB;
C->TemplateMethod();
delete C;
C = NULL;
return 0;
}
大话设计模式例子实现
相同试卷(抽象类),不同的人做会得到不同的结构
#include <iostream>
#include <string>
using namespace std;
//抽象类,相当于AbstractClass
class TestPaper{
public:
//模板方法
void testQuestion1(){
cout << "问题A:a,b,c,d" << endl;
cout << "答案:" << answer1() << endl;
}
void testQuestion2(){
cout << "问题B:a,b,c,d" << endl;
cout << "答案:" << answer2() << endl;
}
void testQuestion3(){
cout << "问题C:a,b,c,d" << endl;
cout << "答案:" << answer3() << endl;
}
//抽象行为
virtual string answer1(){
return "";
}
virtual string answer2(){
return "";
}
virtual string answer3(){
return "";
}
};
//相当于ConcreteClass
//学生试卷A
class TestPaperA: public TestPaper{
public:
string answer1(){
return "A";
}
string answer2(){
return "C";
}
string answer3(){
return "D";
}
};
//学生试卷B
class TestPaperB: public TestPaper{
public:
string answer1(){
return "B";
}
string answer2(){
return "C";
}
string answer3(){
return "D";
}
};
int main(){
cout << "学生A的试卷和答案:" << endl;
TestPaper *stuA = new TestPaperA;
stuA->testQuestion1();
stuA->testQuestion2();
stuA->testQuestion3();
cout << "学生B的试卷和答案:" << endl;
TestPaper *stuB = new TestPaperB;
stuB->testQuestion1();
stuB->testQuestion2();
stuB->testQuestion3();
return 0;
}