一,模板方法模式
1.1,对模板方法模式的理解
模板方法模式: 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
1.2,解决的问题
当要完成在某一细节层次一致的一个过程或一系列步骤,但其个别步骤在更详细的层次上的实现可能不同时,通常考虑使用模板方法模式来处理。通俗的来讲就是,有一些方法比较通用,但是在每一个子类都重写了该方法,正确的做法是将这些通用算法抽象出来,在抽象类实现,其他步骤在子类实现。
1.3,应用场景
做一个抄题目的程序,没有使用模板方法模式
// 试卷类
class TestPaper
{
public:
void question1()
{
cout << "题目一:" << endl;
}
void question2()
{
cout << "题目二:" << endl;
}
}
// 学生甲抄的试卷
class TestPaperA : public TestPaper
{
public:
void answer1()
{
TestPaper::question1();
cout << "答案选 : " << "B" <<endl;
}
void answer2()
{
TestPaper::question2();
cout << "答案选 : " << "C" <<endl;
}
}
// 学生乙抄的试卷
class TestPaperB : public TestPaper
{
public:
void answer1()
{
TestPaper::question1();
cout << "答案选 : " << "A" <<endl;
}
void answer2()
{
TestPaper::question2();
cout << "答案选 : " << "D" <<endl;
}
}
程序分析:
上面两个子类里面重复的代码比较的多,例如:
TestPaper::question1();
与cout << "答案选 : " <<
,除了选项不同其他的都是重复的。既然这里使用到了继承,就应该要成为子类的模板,所有重复的代码都应该上升到父类里去,而不是让每个子类都去重复。下面的例子是使用模板方法模式的版本:
// 试卷类
class TestPaper
{
public:
void question1()
{
cout << "题目一:" << answer1() << endl;
}
void question2()
{
cout << "题目二:" << answer2() << endl;
}
virtual string answer1()
{
return "";
}
virtual string answer2()
{
return "";
}
}
// 学生甲抄的试卷
class TestPaperA : public TestPaper
{
public:
string answer1()
{
return "A";
}
string answer2()
{
return "B";
}
}
// 学生乙抄的试卷
class TestPaperB : public TestPaper
{
public:
string answer1()
{
return "C";
}
string answer2()
{
return "D";
}
}
1.4,模板方法模式的优缺点
优点:
- 提高代码复用性 ,将相同部分的代码放在抽象的父类中。
- 提高了拓展性 ,将不同的代码放入不同的子类中,通过对子类的扩展增加新的行为。
缺点:
- 引入了抽象类,每一个不同的实现都需要一个子类来实现,导致类的个数增加,从而增加了系统实现的复杂度。