模板方法模式(TemplateMethod)定义: 定义一个操作中的算法的骨架,将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。
优点:
子类实现算法的某些细节,有助于算法的扩展。
通过一个父类调用子类实现的操作,通过子类扩展增加新的行为,符合“开放-封闭原则”。
很好的实现了代码复用,把不变的行为放置到超类中,去除子类的重复。
缺点:
每个不同的实现都需要定义一个子类,这会导致类的个数的增加,设计更加抽象。
适用场景:
在某些类的算法中,用了相同的方法,造成代码的重复。
控制子类扩展,子类必须遵守算法规则。
例子背景: 家教老师要给两个学生出同一套题,两个学生太笨题目都分不清顺序,没办法老师要求再考一次,并且让学生把题目(题号)先写下来。
试卷类:
class TestPaper //给出了逻辑骨架,具体实现留到了子类中 { public void TestQuestion1() { Console.WriteLine("考题1的答案是[ ]a. b. c. d."); Console.WriteLine("答案:"+Answer1()); } public void TestQuestion2() { Console.WriteLine("考题2的答案是[ ]a. b. c. d."); Console.WriteLine("答案:" + Answer2()); } public void TestQuestion3() { Console.WriteLine("考题3的答案是[ ]a. b. c. d."); Console.WriteLine("答案:" + Answer3()); } //逻辑的组成是一些抽象的操作,虚方法为了让子类重写自己的答案 protected virtual string Answer1() { return ""; } protected virtual string Answer2() { return ""; } protected virtual string Answer3() { return ""; } }
学生甲的试卷:
class TestPaperA:TestPaper //同学甲、乙可以有不同的实现方法 { protected override string Answer1() { return "b"; } protected override string Answer2() { return "c"; } protected override string Answer3() { return "a"; } }
学生乙的试卷:
class TestPaperB : TestPaper { protected override string Answer1() { return "b"; } protected override string Answer2() { return "c"; } protected override string Answer3() { return "b"; } }
客户端:
static void Main(string[] args) { Console.WriteLine("学生甲的试卷"); //这里使用多态,将子类对象转成父类对象,方便使用父类的方法,实现了代码复用 TestPaper studentA = new TestPaperA(); studentA.TestQuestion1(); studentA.TestQuestion2(); studentA.TestQuestion3(); Console.WriteLine("学生乙的试卷"); TestPaper studentB = new TestPaperB(); studentB.TestQuestion1(); studentB.TestQuestion2(); studentB.TestQuestion3(); Console.ReadLine(); }