1.1概述
定义了一个操作中算法的骨架,而将一些步骤延迟到子类中。模板方法使子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。这就是模板方法的定义。
类中的方法用以表明该类的实例所具有的行为,一个类可以有许多方法,而且类中的实例方法也可以调用该类中的其他若干个方法。在编写类的时候,可能需要将类的许多方法集成到一个实例方法中,即用一个实例方法封装若干个方法的调用,以表现一个算法的骨架,也就是说,调用该实例方法相当于按着一定顺序执行若干个方法。
例如,各类客运车站在安排乘客上车时都进行安全检查、验证车票、选择车体类型三个步骤(具体如下图一所示)。因此在一个抽象类Station中包含安全检查方法(safetyExamine)、验证车票方法(validateTicket)、选择车体类型方法(choiceCarriageType)表示乘车步骤的抽象方法,而且该抽象类中还包含有ridingStep()方法,该方法顺序调用安全检查方法、验证车票方法、选择车体类型方法,也就是说抽象类Station使用ridingStep()方法封装了乘车步骤。ridingStep()方法所调用的safetyExamine()、validateTicket()、choiceCarriageType()方法都是抽象方法,因此Station的子类:RailwayStation(火车站)在实现safetyExamine()、validateTicket()、choiceCarriageType()方法时,分别给出了自己的安全检查方式、检票车票方式和所选车体类型。当Station类声明的变量存放它的子类RailwayStation实例的引用后,该变量就可以调用ridingStep()方法展示乘客的乘车步骤。具体类关系图如下图一所示:
图一:乘车步骤
模板方法是关于怎样将若干个方法集成到一个方法中,以便形成一个解决问题的算法骨架。模板方法模式的关键是在一个抽象类中定义一个算法的骨架,即将若干个方法集成到一个方法中,并称该方法为一个模板方法,或简称为模板。模板方法所调用的其他方法通常称为抽象的方法,这些抽象方法相当于算法骨架中的各个步骤,这些步骤可以由子类去完成。
1.2模式的结构
模板方法模式包括以下两种角色:
(1)抽象模板(Abstract Template):抽象模板是一个抽象类。抽象模板定义了若干个方法以表示算法的各个步骤,这些方法中有抽象方法也有非抽象方法,其中的抽象方法称为原语操作(Primitive Operation)。重要的一点是,抽象模板中还定义了一个称之为模板方法的方法,该方法不仅包含有抽象模板中表示算法步骤的方法调用,而且也可以包含有定义在抽象模板中的其他对象的方法调用,即模板方法定义了算法的骨架。
(2)具体模板(Concrete Template):具体模板是抽象模板的子类,实现抽象模板中的原语操作。
模板方法模式结构的类图如下图二所示:
图二:模板方法模式的类图
1.3模板方法模式的优点
(1)可以通过在抽象模板定义模板方法给出成熟的算法步骤,同时又不限制步骤的细节,具体模板实现细节不会改变整个算法的框架。
(2)在抽象模板模式中,可以通过钩子方法对某些步骤进行挂钩,具体模板通过钩子可以选择算法骨架中的某些步骤。
1.4适合使用模板方法模式的情景
(1)设计者需要给出一个算法的固定步骤,并将某些步骤的具体实现留给子类来实现。
(2)需要对代码进行重构,将各个子类公共行为提取出来集中到一个共同的父类中以避免代码重复。