[设计模式]模板方法模式

1. 定义

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

2. 类图

  

  AbstractClass:抽象类,用来定义算法骨架和原语操作,具体的子类通过重定义这些原语操作来实现一个算法的各个步骤,在这个类中,也可以提供原语的默认实现。

  ConcreteClass:具体实现类。用来实现算法骨架中的某些步骤,完成与特定子类的功能。

3. 示例

  

package com.jerry.designpattern;
/**
 * 
 * @author Jerry
 * @date 2015年1月29日 下午9:38:26
 */
public abstract class Account {
    
    /**
     * 模板方法
     * 定义了算法架构
     * 不同的操作定义为抽象方法,由子类实现
     * @return
     */
    public final double calculateInterest() {
        double interestRate = calculateInterestRate();
        String accountType = calculateAccountType();
        double money = calculateMoney(accountType);
        return interestRate * money;
    }
    
    
    private double calculateMoney(String accountType) {
        // TODO Auto-generated method stub
        return 8343;
    }

    /**
     * 获得账户类型
     * @return
     */
    protected abstract String calculateAccountType();

    /**
     * 获得利息比率
     * @return
     */
    protected abstract double calculateInterestRate();
}

package com.jerry.designpattern;
/**
 * 
 * @author Jerry
 * @date 2015年1月29日 下午9:49:36
 * Certificate of Deposite
 */
public class CDAccount extends Account{
    
    @Override
    protected String calculateAccountType() {
        // TODO Auto-generated method stub
        return "定期存款账号";
    }
    
    @Override
    protected double calculateInterestRate() {
        // TODO Auto-generated method stub
        return 0.065;
    }
}

package com.jerry.designpattern;
/**
 * 
 * @author Jerry
 * @date 2015年1月29日 下午9:48:39
 */
public class MoneyMarketAccount extends Account{

    @Override
    protected String calculateAccountType() {
        // TODO Auto-generated method stub
        return "货币市场账号";
    }

    @Override
    protected double calculateInterestRate() {
        // TODO Auto-generated method stub
        return 0.045;
    }

}

package com.jerry.designpattern;
/**
 * 
 * @author Jerry
 * @date 2015年1月29日 下午9:51:26
 */
public class Client {
    public static void main(String[] args) {
        Account a1 = new MoneyMarketAccount();
        System.out.println("货币市场账号利率金额为:" + a1.calculateInterest());
        
        Account a2 = new CDAccount();
        System.out.println("定期存款账号利率金额为:" + a2.calculateInterest());
    }
}

4. 优缺点

  模板方法模式优点是实现代码复用,通过把子类的公共功能提炼和抽取,把公共部分放到模板中去实现。

  模板方法模式缺点是算法骨架不易升级,通过模板的定制,把算法骨架完全固定下来,事实上模板的子类是非常耦合的,如果要对算法骨架进行更变,可能会要求所有相关子类进行相应的变化。