模板方法模式介绍
模板方法模式定义:
定义一个操作中的算法的骨架,而将一些多变的步骤延迟到子类中实现,使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
解释:对于一个类,把类中多变的部分和不变的部分分离开来,将多变的部分延迟到子类去实现,不变的部分封装在基类中。
优点:
- 封装不变部分,扩展可变部分。
- 提取公共代码,便于维护。
- 行为由父类控制,子类实现。
缺点:
- 每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。
使用场景:
- 对于base class 有多个子类共有的方法,且逻辑相同。
- 重要的、复杂的方法,可以考虑作为模板方法。
实现模板
#include <iostream>
using namespace std;
class AbstractClass
{
public:
virtual void PrimitiveOperation1() = 0;
virtual void PrimitiveOperation2() = 0;
void TemplateMethod()
{
PrimitiveOperation1();
PrimitiveOperation2();
}
};
class ConcreteClassA: public AbstractClass
{
public:
void PrimitiveOperation1()
{
cout << "具体类A方法1实现" << endl;
}
void PrimitiveOperation2()
{
cout << "具体类A方法2实现" << endl;
}
};
class ConcreteClassB: public AbstractClass
{
public:
void PrimitiveOperation1()
{
cout << "具体类B方法1实现" << endl;
}
void PrimitiveOperation2()
{
cout << "具体类B方法2实现" << endl;
}
};
int main()
{
AbstractClass* ac = new ConcreteClassA;
ac->TemplateMethod();
AbstractClass* bc = new ConcreteClassB;
bc->TemplateMethod();
return 0;
}
运行解果:
具体类A方法1实现
具体类A方法2实现
具体类B方法1实现
具体类B方法2实现
应用举例
不变的是试卷的题目(abstract class),可变的是不同学生的答案(concrete class)
// 试题
class TestPaper
{
private:
virtual string Answer1() = 0; // 将可变的与不变的分离
virtual string Answer2() = 0; // 将可变的与不变的分离
void TestQuestion1()
{
cout << "1.大学能谈恋爱不?" << endl;
cout << "A 必须谈 B 不能谈" << endl;
cout << "我的答案:" << Answer1() << endl;
}
void TestQuestion2()
{
cout << "2.大学恋爱正常吗?" << endl;
cout << "A 必须正常 B 可不正常" << endl;
cout << "我的答案:" << Answer2() << endl;
}
public:
void TemplateMethod()
{
TestQuestion1();
TestQuestion2();
}
};
// 学生A的试卷
class TestPaperA : public TestPaper
{
public:
string Answer1()
{
return "A";
}
string Answer2()
{
return "A";
}
};
// 学生B的试卷
class TestPaperB : public TestPaper
{
private:
string Answer1()
{
return "A";
}
string Answer2()
{
return "B";
}
};
int main()
{
TestPaper* student1 = new TestPaperA;
student1->TemplateMethod();
TestPaper* student2 = new TestPaperB;
student2->TemplateMethod();
return 0;
}
运行结果:
1.大学能谈恋爱不?
A 必须谈 B 不能谈
我的答案:A
2.大学恋爱正常吗?
A 必须正常 B 可不正常
我的答案:A
1.大学能谈恋爱不?
A 必须谈 B 不能谈
我的答案:A
2.大学恋爱正常吗?
A 必须正常 B 可不正常
我的答案:B
总结
- 模板方法是通过把不变的行为搬移到base class,去除子类中的重复代码来体现它的优势。
- 当不变的和可变的行为在方法的此类实现中混合在一起的时候,不变的行为就会在子类中重复出现。我们通过模板方法模式把这些行为搬移到单一的地方。这就帮助此类摆脱重复的不便行为的纠缠。