在一个操作方法中定义算法的流程,某些步骤由子类完成。模板方法模式让子类在不变更原有算法流程的情况下,还能重新定义其中的步骤。
举个栗子,现在巧克力和香子兰两个人肚子饿了,要吃饭。吃饭的过程有三个步骤:
1.吃配菜;
2.吃主食;
3.喝饮料;
虽然吃饭步骤一样,可是两个人吃的东西却不同。巧克力配菜要吃西红柿炒鸡蛋,主食要吃馒头,饮料要喝可乐;而香子兰要吃麻婆豆腐,米饭和牛奶。
如果用程序表示的话,可以看出二者使用相同的验算流程,且实现的内容不一样。一般情况下我们会分别给二者写一套代码,这样做没有什么问题。可是如果后续开发需要添加新的功能呢,比如说红豆,时雨也要吃饭饭。或者她们想改变下吃饭的流程,先吃主食再吃配菜呢?是不是要为每套代码做出修改?显而易见这样的实现不太好,那么有没有一种好的实现方法呢?
答案就是使用模板方法模式(Template)
偷来的结构图_(:з」∠)_
1.定义一个算法的流程,即是很明确的定义算法的每一个步骤,并写在父类的方法中,而每一个步骤都可以是一个方法的调用。
2.某些步骤由子类完成。
代码实现
算法定义类:
由一个主方法和三个步骤方法组成,主方法不可重写,步骤方法必须在子类实现:
abstract class IEat { public void Eat() { EatDishes(); EatStaple(); Drink(); } protected abstract void EatDishes(); protected abstract void EatStaple(); protected abstract void Drink(); }
算法步骤的实现类:
巧克力:
class ChocolatEat : IEat { protected override void EatDishes() { Console.WriteLine("配菜:西红柿炒鸡蛋"); } protected override void EatStaple() { Console.WriteLine("主食:馒头"); } protected override void Drink() { Console.WriteLine("饮料:可乐"); } }
香子兰:
class VinillaEat : IEat { protected override void EatDishes() { Console.WriteLine("配菜:麻婆豆腐"); } protected override void EatStaple() { Console.WriteLine("主食:米饭"); } protected override void Drink() { Console.WriteLine("饮料:牛奶"); } }
在Main中调用:
static void Main(string[] args) { ChocolatEat chocolat = new ChocolatEat(); VinillaEat vinilla = new VinillaEat(); Console.WriteLine("巧克力吃了:"); chocolat.Eat(); Console.WriteLine("-------------"); Console.WriteLine("香子兰吃了:"); vinilla.Eat(); }
结果:
结论
模板方法模式将可能出现重复的“算法流程”从子类提升到父类中,减少重复的发生,并且也开放子类参与算法中各个步骤的执行或优化。但如果“算法流程”开放太多的步骤,并要求子类必须全部重新实现的话,反而会造成实现的困难,也不容易维护。