一、定义
在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中,使得子类可以不改变算法结构的情况下,重定义该算法中的某些特定步骤。
比较通俗的说法,子类决定如何实现算法中的某些步骤,比如两个一连串的操作,操作次序是一样的,有的操作相同,有的不同,将两个连串操作抽象出父类;
子类在相同次序,但具体方法不一样的操作 在父类抽象出来,然后在子类重写实现,达到减少重复代码。
二、结构
三、实现
以下以泡茶和泡咖啡为例子
namespace DesignPatterns.Template { /// <summary> /// 模版方法 /// </summary> class Program { static void Main(string[] args) { Tea tea = new Tea(); tea.PrepareRecipe(); Console.WriteLine("==== 我是分界线 ===="); Coffee coffee = new Coffee(); coffee.PrepareRecipe(); } } public class Tea : Beverage { public override void Brew() { Console.WriteLine("冲泡茶叶"); } public override void AddCondiments() { Console.WriteLine("加柠檬"); } } public class Coffee : Beverage { public override void Brew() { Console.WriteLine("冲泡咖啡"); } public override void AddCondiments() { Console.WriteLine("加糖和牛奶"); } } public abstract class Beverage { public void PrepareRecipe() { BoilWater(); Brew(); PourInCup(); AddCondiments(); } public abstract void Brew(); public abstract void AddCondiments(); public void BoilWater() { Console.WriteLine("泡开水"); } public void PourInCup() { Console.WriteLine("倒进杯子"); } } }
结果:
泡开水 冲泡茶叶 倒进杯子 加柠檬 ==== 我是分界线 ==== 泡开水 冲泡咖啡 倒进杯子 加糖和牛奶 请按任意键继续. . .
四、适用场景
在多个子类拥有相同的方法,并且这些方法逻辑相同时,可以考虑使用模版方法模式。在程序的主框架相同,细节不同的场合下,也比较适合使用这种模式。
五、优缺点
优点:
模板方法模式通过把不变的行为搬移到超类,去除了子类中的重复代码。
子类实现算法的某些细节,有助于算法的扩展。
通过一个父类调用子类实现的操作,通过子类扩展增加新的行为,符合“开放-封闭原则”。
缺点:
每个不同的实现都需要定义一个子类,导致类的个数增加,设计更加抽象;
子类的实现也可以影响父类中主逻辑的运行,在灵活的同时,由于子类影响到了父类,违反了里氏替换原则,也会给程序带来风险。这就对抽象类的设计有了更高的要求。