模板方法模式
2017-12-14 本文已影响12人
icecrea
Java的集合就是一个典型的,利用了模板方法模式的例子。Java集合中的Collection集合包括List和Set两大组成部分。List是队列,而Set是没有重复元素的集合。它们共同的接口都在Collection接口声明;例如,都包含了size(),isEmpty()方法。而AbstractCollection这个抽象类则实现了它们共同的方法,其余未实现的方法定义为抽象方法。List和Set的实例类,就是通过继承AbstractCollection(或它的子类),省去了许多重复性编码的工作!
模板方法
一个模板方法是定义在抽象类中的,把基本操作方法组合在一起形成一个总算法或一个总行为的方法。
一个抽象类可以有任意多个模板方法,而不限于一个。每一个模板方法都可以调用任意多个具体方法。
基本方法
基本方法又可以分为三种:抽象方法(Abstract Method)、具体方法(Concrete Method)和钩子方法(Hook Method)。
• 抽象方法: 一个抽象方法由抽象类声明,由具体子类实现。在Java语言里抽象方法以abstract关键字标示。
• 具体方法: 一个具体方法由抽象类声明并实现,而子类并不实现或置换。
• 钩子方法: 一个钩子方法由抽象类声明并实现,而子类会加以扩展。通常抽象类给出的实现是一个空实现,作为方法的默认实现。
abstract public class AbstractClass {
// 模板方法
public void templateMethod(){
hookMethod(); //调用基本方法(由子类实现)
abstractMethod(); //调用基本方法(由子类实现)
concreteMethod(); //调用基本方法(已经实现)
}
// 基本方法的声明(由子类实现,但抽象模板给出了默认实现)
public void hookMethod() {}
// 基本方法的声明(由子类实现)
public abstract void abstractMethod();
// 基本方法(已经实现)
public final void concreteMethod(){
// do something
}
}
public class ConcreteClass extends AbstractClass {
// 基本方法的实现
@Override
public void hookMethod() {
// do something
}
// 基本方法的实现
@Override
public void abstractMethod() {
// do something
}
}
具体代码参考:
抽象模板类:
abstract public class Account {
protected String accountNumber;
public Account() {
accountNumber = null;
}
public Account(String accountNumber) {
this.accountNumber = accountNumber;
}
// 模板方法,计算利息数额
public final double calculateInterest(){
double interestRate = doCalculateInterestRate();
String accountType = doCalculateAccountType();
double amount = calculateAmount(accountType, accountNumber);
return amount * interestRate;
}
// 基本方法留给子类实现
protected abstract String doCalculateAccountType();
// 基本方法留给子类实现
protected abstract double doCalculateInterestRate();
// 基本方法,已经实现
private double calculateAmount(String accountType, String accountNumber){
// retrive amount from database
return 7243.00D;
}
}
具体子类实现
public class MoneyMarketAccount extends Account {
@Override
protected String doCalculateAccountType() {
return "Money Market";
}
@Override
protected double doCalculateInterestRate() {
return 0.045D;
}
}