1. 模板方法模式
准备一个抽象类,将部分逻辑以具体方法以及具体构造子的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。这就是模版方法模式的用意。
很多人可能没有想到,模版方法模式实际上是所有模式中最为常见的几个模式之一,而且很多人可能使用过模版方法模式而没有意识到自己已经使用了这个模式。模版方法模式是基于继承的代码复用的基本技术,模版方法模式的结构和用法也是面向对象设计的核心。
模版方法模式需要开发抽象类和具体子类的设计师之间的协作。一个设计师负责给出一个算法的轮廓和骨架,另一些设计师则负责给出这个算法的各个逻辑步骤。代表这些具体逻辑步骤的方法称做基本方法(primitive method);而将这些基本法方法总汇起来的方法叫做模版方法(template method),这个设计模式的名字就是从此而来。
2. 模板方法模式结构
这里涉及到两个角色:
抽象模版(AbstractClass)角色有如下的责任:定义了一个或多个抽象操作,以便让子类实现。这些抽象操作叫做基本操作,它们是一个顶级逻辑的组成步骤。定义并实现了一个模版方法。这个模版方法一般是一个具体方法,它给出了一个顶级逻辑的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类实现。顶级逻辑也有可能调用一些具体方法。
具体模版(ConcreteClass)角色有如下的责任:实现父类所定义的一个或多个抽象方法,它们是一个顶级逻辑的组成步骤。每一个抽象模版角色都可以有任意多个具体模版角色与之对应,而每一个具体模版角色都可以给出这些抽象方法(也就是顶级逻辑的组成步骤)的不同实现,从而使得顶级逻辑的实现各不相同。
3. 模版方法模式中的方法
模版方法中的方法可以分为两大类:模版方法(Template Method)和基本方法(Primitive Method)。
模版方法
一个模版方法是定义在抽象类中的,把基本操作方法组合在一起形成一个总算法或一个总行为的方法。这个模版方法一般会在抽象类中定义,并由子类不加以修改地完全继承下来。
基本方法
基本方法又可以分为三种:抽象方法(Abstract Method)、具体方法(Concrete Method)和钩子方法(Hook Method)。
1) 抽象方法:一个抽象方法由抽象类声明,由具体子类实现。在C#语言里一个抽象方法以abstract关键字标示出来。
2)具体方法:一个具体方法由抽象类声明并实现,而子类并不实现或置换。在C#语言里面,一个具体方法没有abstract关键字。
3) 钩子方法:一个钩子方法由抽象类声明并实现,而子类会加以扩展。通常抽象类给出的实现是一个空实现,作为方法的默认实现。(Visual FoxPro中项目向导建立的项目会使用一个AppHook类实现监视项目成员变化,调整系统结构的工作。)钩子方法的名字通常以do开始。
4. 模板方法模式示例
- using System;
- using System.Data;
- // 模板方法抽象类
- public abstract class AbstractMethod
- {
- // 基本方法
- public abstract bool ConnectDataBase();
- // 基本方法
- public abstract DataSet GetData();
- // 基本方法
- public abstract int ExecQueryNon();
- // 基本方法
- public abstract void DisconnectDataBase();
- // 模板方法
- public void Process()
- {
- if (ConnectDataBase() == true)
- {
- int ss = ExecQueryNon();
- if (ss > 0)
- {
- DataSet ds = GetData();
- }
- DisconnectDataBase();
- }
- }
- }
- // 模板方法抽象子类
- public class ConcreteMethod : AbstractMethod
- {
- public override bool ConnectDataBase()
- {
- return true;
- }
- public override DataSet GetData()
- {
- return new DataSet();
- }
- public override int ExecQueryNon()
- {
- return 11;
- }
- public override void DisconnectDataBase()
- {
- return;
- }
- }
- // 应用实例
- public static class Main
- {
- public void doSearch()
- {
- // 实例化抽象子类,继承基类模板方法【Process()】
- ConcreteMethod method = new ConcreteMethod();
- method.Process();
- }
- }