**模板方法模式:定义一个操作中的算法骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。
模板方法模式角色:
1:抽象类角色(AbstractClass):定义一个模板方法(TemplateMethod),在该方法中包含着一个算法的骨架,具体的算法步骤是PrimitiveOperation1方法和PrimitiveOperation2方法,该抽象类的子类将重定义PrimitiveOperation1和PrimitiveOperation2操作。
2:具体类角色(ConcreteClass):实现PrimitiveOperation1方法和PrimitiveOperation2方法以完成算法中与特定子类(Client)相关的内容。 在模板方法模式中,AbstractClass中的TemplateMethod提供了一个标准模板,该模板包含PrimitiveOperation1和PrimitiveOperation2两个方法,这两个方法的内容Client可以根据自己的需要重写。**
模板方法模式是基于继承的代码复用基本技术,在模板方法模式中,可以将相同的代码放在父类中,而将不同的方法实现放在不同的子类中。
模板方法的实现精髓:
把相同的部分抽象出来到抽象类中去定义,具体子类来实现具体的不同部分。
这里使用抄作业的例子来实现模板方法模式。
抄作业嘛,老师把卷子都发下来了,选择题只需要抄写其对应的选项就好了,如果发现抄错了,那只需要修改你抄的选项就可以了,修改相当灵活。
1:我们需要将卷子的内容放到一个抽象类中,因为两张卷子除了答案,题目和选项都是相同的。
2:就是我们需要写的答案了,我们需要修改的也只有我们自己填写的答案。
上代码:
模板类:Templates.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace templates { public abstract class Templates { /// <summary> /// 问题一 /// </summary> public void QuestionOne() { Console.WriteLine("26个英文字母开头是什么?A:a B:z"); } /// <summary> /// 问题二 /// </summary> public void QuestionTwo() { Console.WriteLine("camellia中文翻译是什么? A:花 B:山茶花"); } // ============= 抽象方法 ==================================== /// <summary> /// 回答一 /// </summary> public abstract void AnswerOne(); /// <summary> /// 回答二 /// </summary> public abstract void AnswerTwo(); } }
子类:QuestionA.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace templates { public class QuestionA:Templates { public override void AnswerOne() { Console.WriteLine("a"); } public override void AnswerTwo() { Console.WriteLine("b"); } } }
子类:QuestionB.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace templates { public class QuestionB:Templates { public override void AnswerOne() { Console.WriteLine("b"); } public override void AnswerTwo() { Console.WriteLine("b"); } } }
客户端调用:Program.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace templates { /// <summary> /// 模板模式客户端 /// </summary> class Program { static void Main(string[] args) { QuestionA xiaoli = new QuestionA(); // 学生小李第一题答案 xiaoli.QuestionOne(); xiaoli.AnswerOne(); // 学生小李第二题答案 xiaoli.QuestionTwo(); xiaoli.AnswerTwo(); Console.WriteLine("---------------------------------------------------"); QuestionB xiaowang = new QuestionB(); // 学生小王第一题答案 xiaowang.QuestionOne(); xiaowang.AnswerOne(); // 学生小王第二题答案 xiaowang.QuestionTwo(); xiaowang.AnswerTwo(); Console.ReadLine(); } } }
模板方法模式总结
优点
1. 模板方法模式通过把不变的行为搬移到超类,去除了子类中的重复代码。
2. 子类实现算法的某些细节,有助于算法的扩展。
3. 通过一个父类调用子类实现的操作,通过子类扩展增加新的行为,符合“开放-封闭原则”。
缺点
1. 每个不同的实现都需要定义一个子类,这会导致类的个数的增加,设计更加抽象。
适用场景
1.在某些类的算法中,用了相同的方法,造成代码的重复。
2.控制子类扩展,子类必须遵守算法规则。