类别:行为型设计模式
目的:定一个代码模板,确保代码执行时会把模板中的代码一并执行,降低漏写约定代码的可能
完整代码参考:1drv.ms/u/s!AquRvPz…
典型场景
这里拿集成支付网关举例,比如业务中对支付的抽象如下
方法 | 作用 |
---|---|
create | 发起支付 |
query | 查询订单 |
refund | 退款 |
在上面执行的每一步进行日志记录
对应的接口Pay.java参考如下
public interface Pay {
void create();
void query();
void refund();
}
复制代码
实现一个支付方式,比如支付宝支付,在每一个支付步骤进行日志记录,参考如下:
import java.util.logging.Logger;
public class AliPay implements Pay {
Logger logger = Logger.getLogger(Pay.class.getName());
@Override
public void create() {
logger.info("alipay create");
System.out.println("call alipay create api");
}
@Override
public void query() {
logger.info("alipay query");
System.out.println("call alipay query api");
}
@Override
public void refund() {
logger.info("alipay refund");
System.out.println("call alipay refund api");
}
}
复制代码
上面代码由一个人维护是ok的,但是如果由另一个人新增一个支付(即实现另一个Pay接口)比如微信支付,可能无法保证日志记录相关代码会被编码了,这种情况就可以使用模板方法模式
模式实现
Pay接口修改抽象类,并把日志记录相关代码移入Pay抽象类中,参考如下:
public abstract class Pay {
Logger logger = Logger.getLogger(Pay.class.getName());
public void create() {
logger.info("alipay create");
doCreate();
}
public void query() {
logger.info("alipay query");
doQuery();
}
public void refund() {
logger.info("alipay refund");
doRefund();
}
abstract protected void doCreate();
abstract protected void doQuery();
abstract protected void doRefund();
}
复制代码
可以看到
- 把Pay接口改为Pay抽象类后,不改变这个抽象类对外暴露的接口
- 日志记录代码编码在了抽象类中
- 具体发起支付的相关代码抽象在了doxxx方法中
- 这样在实现一个新的支付方式时,实现protected的doxxx系列方法记录,调用方使用create, query, refund进行支付操作
- 确保日志记录代码(模板代码)一定会被执行
上面这个Pay抽象类中的create, query, refund中会被执行的日志记录相关代码即使模板,doxxx系列方法就是需要用户填充到模板中的代码
比如实现一个新的微信支付,参考如下
public class WechatPay extends Pay {
@Override
public void doCreate()
请到「今天看啥」查看全文