在面向对象程序设计过程中,程序员常常会遇到这种情况:设计一个系统时知道了算法所需的关键步骤,而且确定了这些步骤的执行顺序,但某些步骤的具体实现还未知,或者说某些步骤的实现与具体的环境相关。 定义与特点模板方法(Template Method)模式的定义如下:定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。它是一种类行为型模式。 该模式的主要优点如下:
该模式的主要缺点如下:
结构与实现模板方法模式需要注意抽象类与具体子类之间的协作。它用到了虚函数的多态性技术以及“不用调用我,让我来调用你”的反向控制技术。 模式的结构模板方法模式包含以下主要角色: 抽象类(Abstract Class):负责给出一个算法的轮廓和骨架。它由一个模板方法和若干个基本方法构成,这些方法的定义如下:
具体子类(Concrete Class):实现抽象类中所定义的抽象方法和钩子方法,它们是一个顶级逻辑的一个组成步骤。 模板方法模式的结构图如图所示: 模式的实现模板方法模式的代码如下: class Program { static void Main(string[] args) { AbstractClass tm=new ConcreteClass(); tm.TemplateMethod(); Console.Read(); } } //抽象类 public abstract class AbstractClass { public void TemplateMethod() //模板方法 { SpecificMethod(); AbstractMethod1(); AbstractMethod2(); } public void SpecificMethod() //具体方法 { Console.WriteLine("抽象类中的具体方法被调用..."); } public abstract void AbstractMethod1(); //抽象方法1 public abstract void AbstractMethod2(); //抽象方法2 } //具体子类 public class ConcreteClass : AbstractClass { public override void AbstractMethod1() { Console.WriteLine("抽象方法1的实现被调用..."); } public override void AbstractMethod2() { Console.WriteLine("抽象方法2的实现被调用..."); } } 程序的运行结果如下: 抽象类中的具体方法被调用... 抽象方法1的实现被调用... 抽象方法2的实现被调用... 应用场景模板方法模式通常适用于以下场景:
扩展:重写钩子方法在模板方法模式中,基本方法包含:抽象方法、具体方法和钩子方法,正确使用“钩子方法”可以使得子类控制父类的行为。如下面例子中,可以通过在具体子类中重写钩子方法 HookMethod1() 和 HookMethod2() 来改变抽象父类中的运行结果,其结构图如图所示: 程序代码如下: class Program { static void Main(string[] args) { HookAbstractClass tm = new HookConcreteClass(); tm.TemplateMethod(); Console.Read(); } } //含钩子方法的抽象类 public abstract class HookAbstractClass { public void TemplateMethod() //模板方法 { AbstractMethod1(); HookMethod1(); if(HookMethod2()) { SpecificMethod(); } AbstractMethod2(); } public void SpecificMethod() //具体方法 { Console.WriteLine("抽象类中的具体方法被调用..."); } public virtual void HookMethod1(){} //钩子方法1 public virtual bool HookMethod2() //钩子方法2 { return true; } public abstract void AbstractMethod1(); //抽象方法1 public abstract void AbstractMethod2(); //抽象方法2 } //含钩子方法的具体子类 public class HookConcreteClass : HookAbstractClass { public override void AbstractMethod1() { Console.WriteLine("抽象方法1的实现被调用..."); } public override void AbstractMethod2() { Console.WriteLine("抽象方法2的实现被调用..."); } public override void HookMethod1() { Console.WriteLine("钩子方法1被重写..."); } public override bool HookMethod2() { return false; } } |
|