模板方法模式比较简单, 其实就是对一些不可变的业务进行封装, 对可变的部分提供扩展。
那扩展当然就是接口或者抽象类了。 但考虑到又有不可变的部分, 所一抽象类就成了不二的选择。
一个抽象模板类通常包括
1. 基本方法
2. 模板方法
其中的基本方法可能被模板方法调用。
大家都有寄快递的经历, 下面就快递来阐述一下模板方法模式。
先看客户端代码
public class Client {
public static void main(String[] args) {
// 张三选择顺风快递
ExpressTemplate zhangSan = new ShunFengExpress();
// 李四选择圆通快递
ExpressTemplate liSi = new YuanTongExpress();
zhangSan.express();
System.out.println();
liSi.express();
}
}
运行结果:
引用
打电话给顺风快递
我们的取货员正在取货途中
我们走空运,货物已到达,派货员正在送货途中
发货人选择了货到付款, 你需要支付¥999999999999
打电话给圆通快递
我们的取货员正在途中
我们不支持货到付款, 你需要支付¥999999999999
我们靠人走,请一个星期后再查看
再看抽象模板类
public abstract class ExpressTemplate {
// 打电话加快递
public abstract void callExpressCompany();
// 快递公司取货
public abstract void expressCompanyFetchGift();
// 是否货到付款 -- 钩子方法(Hook Method)
public abstract boolean isPayOnReceipt();
// 快递公司送货
public abstract void deliver();
// 发货人付款
public abstract void payBySender();
// 收货人付款
public abstract void payByReceiver();
// 模板方法
public final void express() {
this.callExpressCompany();
this.expressCompanyFetchGift();
// 发货人付款
if (!this.isPayOnReceipt()) {
this.payBySender();
}
this.deliver();
// 货到由收货人付款
if (this.isPayOnReceipt()) {
this.payByReceiver();
}
}
}
再看看两个具体的实现类
public class ShunFengExpress extends ExpressTemplate {
@Override
public void callExpressCompany() {
System.out.println("打电话给顺风快递");
}
@Override
public void deliver() {
System.out.println("我们走空运,货物已到达,派货员正在送货途中");
}
@Override
public void expressCompanyFetchGift() {
System.out.println("我们的取货员正在取货途中");
}
@Override
public boolean isPayOnReceipt() {
return true;
}
@Override
public void payByReceiver() {
System.out.println("发货人选择了货到付款, 你需要支付¥999999999999");
}
@Override
public void payBySender() {
System.out.println("您选择了货到付款, 你需要支付¥999999999999");
}
}
public class YuanTongExpress extends ExpressTemplate {
@Override
public void callExpressCompany() {
System.out.println("打电话给圆通快递");
}
@Override
public void deliver() {
System.out.println("我们靠人走,请一个星期后再查看");
}
@Override
public void expressCompanyFetchGift() {
System.out.println("我们的取货员正在途中");
}
@Override
public boolean isPayOnReceipt() {
return false;
}
@Override
public void payByReceiver() {
System.out.println("货到付款, 你需要支付¥999999999999");
}
@Override
public void payBySender() {
System.out.println("我们不支持货到付款, 你需要支付¥999999999999");
}
}