模板方法( Template Method )模式:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。 Template Method 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

适用性:

  • 一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。
  • 各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。首先识别现有代码中的不同之处,并且将不同之处分离为新的操作。最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。
  • 控制子类扩展。模板方法只在特定点调用“hook”操作,这样就只允许在这些点进行扩展。

template.bmp

涉及到的角色:

   抽象模板 (Abstract Template) 角色: 1 。定义一个或者多个抽象操作,以便让子类实现,这些抽象操作叫做基本操作,它们是一个顶级逻辑的组成步骤。 2 。定义并实现一个模板方法,这个模板方法一般是具体方法,它给出了顶级逻辑的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类中实现,顶级逻辑也可能调用一些具体方法。

   具体模板 (Concrete Template) 角色:实现父类所定义的一个或多个抽象方法,它是顶级逻辑的的组成步骤。每一个抽象模板角色都可以有任意多个具体模板角色与之相对应,而每一个具体模板角色都可以给出这些抽象方法的不同实现,从而使得顶级逻辑的实现各不相同。

一个具体的例子:
抽象模板:

package  TemplateMethod;

public   abstract   class  Account {
    
protected  String accountNumber;
    
// 默认构造方法
     public  Account() {
        accountNumber
= null ;
    }

    
// 构造方法
     public  Account(String accountNumber) {
        
this .accountNumber = accountNumber;
    }

    
// 模板方法   设计利息数额
     final   public   double  calculateInterest() {
        
double  interestRate = doCalculateInterest();
        String accountType
= doCalculateAccountType();
        
double  amount = calculateAmount(accountType,accountNumber);
        
return  amount *  interestRate;
    }

    
// 基本方法留给子类实现
     protected   abstract   double  doCalculateInterest();
    
// 基本方法留给子类实现
     protected   abstract  String doCalculateAccountType();
    
// 基本方法,已经实现
     protected   double  calculateAmount(String accountType,String accountNumber) {
        
// 一些操作
         return   7243.00D ;
    }

    
}

具体模板:

package  TemplateMethod;

public   class  MoneyMarketAccount  extends  Account {
    
// 基本方法,在这里实现
     public   double  doCalculateInterest() {
        
return   0.045D ;
    }

    
// 基本方法,在这里实现
     public  String doCalculateAccountType() {
        
return   " Money Market " ;
    }

}

package  TemplateMethod;

public   class   CDMarket  extends  Account {
    
// 基本方法,在这里实现
     public   double  doCalculateInterest() {
        
return   0.065D ;
    }

    
// 基本方法,在这里实现
     public  String doCalculateAccountType() {
        
return   " Certificate of Deposite " ;
    }

}

 客户端类:

package  TemplateMethod;

public   class  Client {
    
private   static  Account acc = null ;
    
    
public   static   void  main(String[] args) {
        acc
= new  MoneyMarketAccount();
        System.out.println(
" Interest from Money Market: " + acc.calculateInterest());
        acc
= new  CDMarket();
        System.out.println(
" Interest form Certificate of Deposite: " + acc.calculateInterest());
    }

}


参考资料:
《java与模式》
《设计模式速查找手册》