4.2.1 定义
模板方法模式,定义一个操作中的算法的骨架,将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤
4.2.2 结构图
4.2.3 通用代码
AbstractClass是抽象类,其实就是一抽象模板,定义并实现了一个模板方法,这个模板方法一般是一个具体方法,它给出了一个顶级逻辑的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类实现。顶级逻辑也有可能调用一些具体方法。
public abstract class AbstractClass { public abstract void PrimitiveOperation1(); public abstract void PrimitiveOperation2(); public void TemplateMethod() { PrimitiveOperation1(); PrimitiveOperation2(); Console.WriteLine(""); } }
ConcreteClass,实现父类所定义的一个或多个抽象方法。每一个AbstractClass都可以有任意多个ConcreteClass与之对应,而每一个ConcretClass都可以给出这些抽象方法的不同实现,从而使得顶级逻辑的实现各不相同。
public class ConcreteClassA : AbstractClass { public override void PrimitiveOperation1() { Console.WriteLine("具体A方法1实现"); } public override void PrimitiveOperation2() { Console.WriteLine("具体A方法2实现"); } } public class ConcreteClassB : AbstractClass { public override void PrimitiveOperation1() { Console.WriteLine("具体A方法1实现"); } public override void PrimitiveOperation2() { Console.WriteLine("具体A方法2实现"); } }
客户端调用:
class Program { static void Main(string[] args) { AbstractClass c; c = new ConcreteClassA(); c.TemplateMethod(); c = new ConcreteClassB(); c.TemplateMethod(); Console.ReadLine(); } }
4.2.4 模拟场景
以生活中炒蔬菜为例来实现下模板方法模式,在现实生活中,做蔬菜的步骤都大致相同,如果我们针对每种蔬菜类定义一个烧的方法,这样在每个类中都有很多相同的代码,为了解决这个问题,我们一般的思路肯定是把相同的部分抽象出来到抽象类中去定义,具体子类来实现具体的不同部分。
4.2.5 场景代码实现
public abstract class Vegetable { // 模板方法,不要把模版方法定义为Virtual或abstract方法,避免被子类重写,防止更改流程的执行顺序 public void CookVegetable() { Console.WriteLine("炒蔬菜的一般做法:"); PourOil(); HeatOil(); PourVegetable(); StirFry(); } public void PourOil() { Console.WriteLine("倒油"); } public void HeatOil() { Console.WriteLine("把油加热"); } //油热了倒蔬菜下去,具体哪种蔬菜由子类决定 public abstract void PourVegetable(); public void StirFry() { Console.WriteLine("翻炒"); } } public class Potato : Vegetable { public override void PourVegetable() { Console.WriteLine("倒土豆进锅中"); } } public class ChinestCabbage : Vegetable { public override void PourVegetable() { Console.WriteLine("倒大白菜进锅中"); } } class Program { /// <summary> /// 客户端调用 /// </summary> /// <param name="args"></param> static void Main(string[] args) { Potato potato = new Potato(); potato.CookVegetable(); Console.ReadLine(); } }
4.2.6 使用场景
当不变和可变的行为在方法的子类实现中混在一起的时候,不变的行为就会在子类中重复出现,我们通过模板方法模式把这些行为搬移到单一的地方,这样就帮助子类拜托重复的不变行为的纠缠。