C#设计模式系列:模板方法模式(Template Method)
你去银行取款的时候,银行会给你一张取款单,这张取款单就是一个模板,它把公共的内容提取到模板中,只留下部分让用户来填写。在软件系统中,将多个类的共有内容提取到一个模板中的思想便是模板方法模式的思想。
模板方法模式是基于继承的代码复用基本技术,在模板方法模式中,可以将相同的代码放在父类中,而将不同的方法实现放在不同的子类中。
在模板方法模式中,需要准备一个抽象类,将部分逻辑以具体方法以及具体构造函数形式实现,然后声明一些抽象方法来让子类实现剩余逻辑。不同的子类可以以不同的方式实现这些抽象方法。
1.1>、定义
定义一个操作中算法的骨架,将这些步骤延迟到子类中。模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
1.2>、使用频率
中等
2、模板方法模式结构
2.1>、结构图
2.2>、参与者
模板方法模式参与者:
◊ AbstractClass:定义一个模板,其子类将重定义PrimitiveOperation1和PrimitiveOperation2操作。
◊ ConcreteClass:实现PrimitiveOperation1和PrimitiveOperation2以完成算法中与特定子类(Client)相关的内容。
在模板方法模式中,AbstractClass中的TemplateMethod提供了一个标准模板,该模板包含PrimitiveOperation1和PrimitiveOperation2两个方法,这两个方法的内容Client可以根据自己的需要重写。
3、模板方法模式结构实现
AbstractClass.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.TemplateMethodPattern.Structural { public abstract class AbstractClass { public abstract void PrimitiveOperation1(); public abstract void PrimitiveOperation2(); /// <summary> /// The "Template method" /// </summary> public void TemplateMethod() { PrimitiveOperation1(); PrimitiveOperation2(); Console.WriteLine(""); } } }
ConcreteClassA.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.TemplateMethodPattern.Structural { public class ConcreteClassA : AbstractClass { public override void PrimitiveOperation1() { Console.WriteLine("ConcreteClassA.PrimitiveOperation1()"); } public override void PrimitiveOperation2() { Console.WriteLine("ConcreteClassA.PrimitiveOperation2()"); } } }
ConcreteClassB.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.TemplateMethodPattern.Structural { public class ConcreteClassB : AbstractClass { public override void PrimitiveOperation1() { Console.WriteLine("ConcreteClassB.PrimitiveOperation1()"); } public override void PrimitiveOperation2() { Console.WriteLine("ConcreteClassB.PrimitiveOperation2()"); } } }
Program.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using DesignPatterns.TemplateMethodPattern.Structural; namespace DesignPatterns.TemplateMethodPattern { class Program { static void Main(string[] args) { AbstractClass aA = new ConcreteClassA(); aA.TemplateMethod(); AbstractClass aB = new ConcreteClassB(); aB.TemplateMethod(); } } }
运行输出:
ConcreteClassA.PrimitiveOperation1()
ConcreteClassA.PrimitiveOperation2()
ConcreteClassB.PrimitiveOperation1()
ConcreteClassB.PrimitiveOperation2()
请按任意键继续. . .
4、模板方法模式应用分析
模板方法模式适用情形:
◊ 一次性实现一个算法的不变部分,并将可变的行为留给子类来实现。
◊ 各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。
◊ 控制子类扩展。模板方法只允许在特定点进行扩展,而模板部分则是稳定的。
模板方法模式特点:
◊ TemplateMethod模式是一种非常基础性的设计模式,在面向对象系统中大量应用。它用最简洁的机制(基础、多态)为很多应用程序框架提供了灵活的扩展点,是代码复用方面的基本实现结构。
◊ 在具体实现方面,被TemplateMethod调用的虚方法可以具有实现,也可以没有任何实现(抽象方法或虚方法)。但一般推荐将它们设置为protected方法使得只有子类可以访问它们。
◊ 模板方法模式通过对子类的扩展增加新的行为,符合“开闭原则”。