共计 3773 个字符,预计需要花费 10 分钟才能阅读完成。
1 概述
1.1 引言
模板办法模式是构造最简略的行为型设计模型,在其构造中只存在父类与之类之间的继承关系,通过应用模板办法模式,能够将一些简单流程的实现步骤封装在一系列根本办法中,在形象父类提供一个称之为模板办法的办法来定义这些根本办法的执行秩序,而通过其子类来笼罩某些步骤,从而使得雷同的算法框架能够有不同的执行后果。模板办法提供了一个模板办法来定义算法框架,而某些具体步骤的实现能够在其子类中实现。
1.2 定义
模板办法模式:定义一个操作中算法的框架,而将一些步骤提早到子类中,模板办法使得子类能够不扭转一个算法的构造即可重定义该算法的某些步骤。
模板办法模式是一品种行为型模式。
1.3 结构图
1.4 角色
AbstractClass
(抽象类):抽象类中定义了一系列基本操作,这些操作是具体的也能够是形象的,每一个基本操作对应算法的一个步骤,在子类中能够重定义或实现这些步骤,同时抽象类实现了一个模板办法,定义一个算法的框架ConcreteClass
(具体子类):实现父类中的形象根本办法,或者笼罩父类中具体基本操作
1.5 模板办法与根本办法
1.5.1 模板办法
模板办法是在抽象类中定义的,把基本操作办法组合成一个总算法或总行为的办法。模板办法在抽象类中定义,并由子类不加以批改齐全继承。模板办法是一个具体方法,给出了一个顶层逻辑框架,而逻辑的组成步骤在抽象类中能够是具体方法,也能够是形象办法。另外因为模板办法是具体方法,因而形象层只能实现为抽象类而不能是接口。
1.5.2 根本办法
根本办法是实现算法的各个步骤,是模板办法的组成部分。根本办法又能够分为三种:
- 形象办法:形象办法就是在抽象类中申明并由子类实现的办法
- 具体方法:具体方法能够由抽象类实现,或者由子类笼罩实现
- 钩子办法:钩子办法能够由抽象类实现,子类能够加以扩大
在模板办法模式中,钩子办法个别有两类:
- 第一类钩子办法是能够与一些具体步骤挂钩,以实现在不同条件下执行模板办法的不同步骤,这类办法个别返回
boolean
,办法名个别为isXXX
- 第二类钩子办法是实现体为空的具体方法,子类能够依据须要笼罩或者继承这些钩子办法
2 典型实现
2.1 步骤
- 定义抽象类:申明模板办法以及根本办法
- 定义模板办法:模板办法是抽象类中的具体方法,依照理论须要将根本办法进行组合
- 定义根本办法:定义形象办法,具体方法以及钩子办法,确定好哪些办法交由抽象类实现,哪些办法交由子类实现以及领有哪些钩子办法
- 定义具体子类:实现抽象类的形象办法,依照须要对钩子办法或者具体方法进行笼罩
2.2 抽象类
abstract class AbstractClass
{public void templateMethod()
{primitiveOperation1();
primitiveOperation2();
if(primitiveOperation3())
System.out.println("合乎钩子办法条件");
else
System.out.println("不合乎钩子办法条件");
primitiveOperation4();}
public void primitiveOperation1()
{System.out.println("抽象类具体方法");
}
// 抽象类形象办法
abstract public void primitiveOperation2();
// 第一类钩子办法
public boolean primitiveOperation3()
{return false;}
// 第二类钩子办法
public void primitiveOperation4()
{}}
首先定义了模板办法,作为客户端操作的入口。模板办法中对根本办法进行了组合,这里申明了四个根本办法:
- 第一个是抽象类的具体方法:这是所有子类都领有的雷同实现的办法,不应该被子类笼罩
- 第二个是抽象类的形象办法:子类须要实现该办法以实现变动
- 第三个是第一类钩子办法:这类钩子办法返回一个
boolean
,能够用于管制是否执行某个步骤,子类能够通过这类钩子办法对模板办法的执行过程进行限度,比方如果不想执行某个步骤能够永远返回false
- 第四个是第二类钩子办法:这类钩子办法中父类提供一个空实现,子类选择性进行笼罩
2.3 具体子类
class ConcreteClass extends AbstractClass
{public void primitiveOperation2()
{System.out.println("子类具体方法");
}
public boolean primitiveOperation3()
{
return true;
// 如果想钩子办法返回 false 能够不实现该办法
// 因为父类默认返回 false
// return false;
}
public void primitiveOperation4()
{System.out.println("子类笼罩父类第二类钩子办法");
}
}
这里子类实现了抽象类的形象办法,同时笼罩了两类钩子办法。
2.4 客户端
public static void main(String[] args)
{AbstractClass class1 = new ConcreteClass();
class1.templateMethod();}
客户端调用很简略,创立一个具体类对象并执行其中的模板办法即可。
输入:
3 实例
为银行业务开发一个利息计算模块,该计算模块领有规范流程:系统验证用户信息,接着判断用户状态,失常状态用户能计算利息,受限制状态用户无奈计算利息,最初显示利息,应用模板办法模式进行设计。
设计如下:
- 抽象类:
Account
- 具体方法:
validate(String name)
- 形象办法:
calculate()
- 钩子办法:
canCalculate()
+display()
- 具体子类:
NormalAccount
+RestrictedAccount
首先是抽象类的设计:
abstract class Account
{public void handle(String name)
{if(validate(name))
{if(canCalculate())
{calculate();
}
display();}
else
{System.out.println("用户名非法");
}
}
public boolean validate(String name)
{return "1".equals(name);
}
// 抽象类形象办法
abstract public void calculate();
// 第一类钩子办法
public boolean canCalculate()
{return true;}
// 第二类钩子办法
public void display()
{}}
首先通过 validate()
验证用户名,接着依据第一类钩子办法 canCalculate()
判断是否计算利息,而后调用形象计算方法 calculate()
进行计算,最初无论可能计算利息都会调用第二类钩子办法display()
。
具体子类代码如下:
class NormalAccount extends Account
{public void calculate()
{System.out.println("失常状态用户计算利息");
}
public void display()
{System.out.println("失常状态用户显示利息");
}
}
class RestrictedAccount extends Account
{public boolean canCalculate()
{return false;}
public void calculate()
{}
public void display()
{System.out.println("受限状态用户无奈计算利息");
}
}
失常状态用户中实现形象办法 calculate()
,并笼罩第二类钩子办法display()
,对于受限状态用户,笼罩了第一类钩子办法canCalculate()
,永远返回false
,同时对形象办法calculate
提供空实现,最初也对第二类钩子办法 display
进行了笼罩,提醒"无奈计算利息"
。
4 次要长处
- 形式化算法:模板办法模式在父类中形式化地定义一个算法,而由子类来实现细节的解决,在子类实现具体的解决算法时并不会扭转算法中步骤的执行秩序
- 代码复用:模板办法模式是一种代码复用技术,提取公共行为并放在父类中,通过子类实现不同的行为
- 实现反向管制:模板办法模式可实现一种反向控制结构,通过子类笼罩父类的钩子办法来决定某一特定步骤是否执行
- 减少子类不便:模板办法模式中可通过子类笼罩父类的根本办法,不同子类能够提供根本办法的不同实现,更换以及减少新的子类很不便
5 次要毛病
- 子类数量多:模板办法模式须要为每一个根本办法的不同实现提供一个子类,如果父类可变的根本办法太多,将会导致类的个数减少,零碎更加宏大,设计也更加形象
6 实用场景
- 对一些简单算法进行宰割,将其算法中固定不变的局部设计为模板办法和父类办法,而一些扭转的细节由子类实现,也就是一次性实现算法中不变局部,并将可变局部交由子类实现
- 各子类中公共的行为应被提取进去并集中到一个公共父类中以防止代码反复
- 须要通过子类决定父类算法中某个步骤是否执行,实现子类对父类的反向管制
7 总结
如果感觉文章难看,欢送点赞。
同时欢送关注微信公众号:氷泠之路。