1.概念
(1)模板方法是基于继承的代码复用技术,在模板方法模式中,可以将相同的代码放在父类之中,而讲不同的方法实现放在不同 的子类之中。
(2)在模板方法之中,我们需要一个抽象类,将部分逻辑以具体方法以及具体构造函数的方式实现。然后声明一些抽象方法让子类实现剩余的逻辑。
(3)模板方法是一种类行为模式。
2.结构
模板方法模式包含的角色
AbstractClass :抽象类
ConcreteClass:具体子类
模板基本方法的组成部分:
抽象方法(AbstrsctCalss Method)
具体方法(Concrete Method)
钩子方法(Hook Method)
3.应用
广泛应用于框架技术(Spring、struts,TestCase..........).
4.模式扩展
好莱坞原则"( Don't call us,we'll call you)
(1)机制
子类不显式的调用父类的方法,而是通过覆盖父类的放法来实现某些具体的业务逻辑,【父类控制对子类的调用】
(2)体现
子类不要调用父类,而通过父类来调用子类,将某些实现的方法写在子类中,让父类来控制整个过程。
(3).钩子(Hook Method)方法的使用
1.使子类可以控制父类的行为
2.最简单的钩子方法就是空方法,也可以再钩子方法中定义一个默认的实现。如果子类不覆盖钩子方法,就执行父类默认实现的代码
3.复杂的钩子方法可以对其他的方法约束,这种钩子通常返回一个boolean类型(true或false),用来判断是否执行一个基本方法
4.示例:
public void temp{
open();
display();
if(isPrint())
{
print();
}}
//判断函数-----钩子方法
public boolean isPrint(){
return true;
}
5.模板方法的具体示例:
每家银行,有不同的存储类型(活期、定期等),因每家银行存储方式的利率不同,所以有不同的收益,请编程计算不同银行的年收益。收益=本金+(本金*利率)
Account接口类:
package com.accp.ven;
/**
* 计算收益的接口
* @author wen
*
*/
public interface Account {
/**获取收益*/
public double getinComing();
/**获取利率*/
public double getRate();
}
实现Account的类
package com.accp.ven;
/**
* 收益接口的实现类
* @author wen
*
*/
public abstract class BaseAccount implements Account {
private double balance;//余额
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
@Override
public double getinComing() {
return balance+(balance*getRate());
}
@Override
/**
* 不同的存储l类型有不同的利率,因此把次方法改写成abstract方法,供子类去实现(模板方法)
*/
public abstract double getRate();
}
package com.accp.ven;
import java.util.HashMap;
import java.util.Map;
/***
* 利率表
* @author wen
*
*/
public class RateTable {
private static Map<String, Double> map = new HashMap<String, Double>();
static{
map.put("a1", 0.1212);
map.put("a2", 0.012);
map.put("b1", 0.333);
}
/**
* 通过key-value获取value
*/
public static double getRateByType(String type) {
return map.get(type);
}
}
package com.accp.ven;
//工具类
public class AccountUtil {
private AccountUtil() {
}
public static double calc(Account act) {
return act.getinComing();
}
}
package com.accp.ven;
//农业银行
public class ABCAccount extends BaseAccount {
@Override
public double getRate() {
return RateTable.getRateByType("a2");
}
}
package com.accp.ven;
//邮政银行
public class YZAccount extends BaseAccount {
@Override
public double getRate() {
return RateTable.getRateByType("b1");
}
}