目录
意图(Intent)
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Template Method使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。
结构(Structure)
其中,
AbstractClass:实现了一个模板方法,定义了算法的骨架,具体子类将重定义PrimitiveOperation以实现一个算法的步骤。
ConcreteClass:实现PrimitiveOperation以完成算法中与特定子类相关的步骤。
Template Method模式的结构要点
1.Template Method模式是一种非常基础性的设计模式,在面向对象系统中有着大量的应用。它用最简洁的机制(虚函数的多态性)为很多应用程序框架提供了灵活的扩展点,是代码复用方面的基本实现结构。
2.除了可以灵活应对子步骤的变化外,“不要调用我,让我来调用你”的反向控制结构是Template Method模式的典型应用。
3.在具体实现方面,被Template Method调用的虚方法可以具有实现,也可以没有任何实现(抽象方法、纯虚方法),但一般推荐将它们设置为protected方法。
应用场景
1.一次性实现一个算法的不变部分,并将可变的行为留个子类来实现。
2.各个子类中公共的行为应被提取出来并集中到一个公共父类中,以避免代码重复。
Example
背景:在考试中,每个学生都有一份纸卷,但是试卷的题目是一样的,只是每个人的答案不一样。也就是说,试卷题目是不变的,变得部分就是答案。
代码实现
试卷类:对应结构图中的AbstractClass
Question1(),Question2(), Question3()方法分别代表3道题目,对应结构图中的TemplateMethod()模板方法,它们是具体不需要改变的方法。
Answer1(),Answer2(), Answer3()写3个问题的答案是virtual虚方法,此方法可以给继承的子类进行重写,因为每个人的答案都是不同的,虚方法对应结构图中的PrimitiveOperation()。
class TestPaper
{
//题目1
public void Question1()
{
Console.WriteLine("商法属于? A.技术性的法B.伦理性的法C.判例法D.习惯法");
Console.WriteLine("答案:"+Answer1());
}
//此方法可以给继承的子类进行重写,因为每个人的答案都是不同的
protected virtual string Answer1()
{
return "";
}
//题目2,3同题目1代码......
}
学生子类,对应于结构图中的ConcreteClass,可以重写TestPaper类里面的虚方法,将答案填写上
用两个学生A和B,每个学生的答案都不同,所以都需要对虚方法进行重写
学生甲的试卷
class TestPaperA : TestPaper
{
protected override string Answer1()
{
return "A";
}
protected override string Answer2()
{
return "D";
}
protected override string Answer3()
{
return "C";
}
}
学生乙的试卷
class TestPaperB : TestPaper
{
protected override string Answer1()
{
return "C";
}
//Answer2(),Answer3()代码同上
}
客户端代码
Console.WriteLine("学生甲的试卷");
TestPaper stuA = new TestPaperA();
stuA.Question1();
stuA.Question2();
stuA.Question3();
Console.WriteLine("学生乙的试卷");
TestPaper stuB = new TestPaperB();
stuB.Question1();
stuB.Question2();
stuB.Question3();
这样就实现了模板方法,将子类中不变的地方分离出来放到父类当中,将可变的方法写成虚方法供子类扩展。