模板方法模式(Template Method Pattern)定义一个操做中算法的框架,而将一些步骤延迟到子类中。模板方法模式使得子类能够不改变一个算法的结构便可重定义该算法的某些特定步骤。java
模板方法模式是结构最简单的行为型设计模式,在其结构中只存在父类与子类之间的继承关系。经过使用模板方法模式,能够将一些复杂流程的实现步骤封装在一系列基本方法中,在抽象父类中提供一个称之为模板方法的方法来定义这些基本方法的执行次序,而经过其子类来覆盖某些步骤,从而使得相同的算法框架能够有不一样的执行结果。算法
模板方法中的方法能够分为两大类:模板方法和基本方法。设计模式
一个模板方法是定义在抽象类中的,把基本操做方法组合在一块儿造成一个总算法或一个总行为的方法。 一个抽象类能够有任意多个模板方法,而不限于一个。每个模板方法均可以调用任意多个具体方法。服务器
基本方法又能够分为三种:抽象方法(Abstract Method)、具体方法(Concrete Method)和钩子方法(Hook Method)。微信
对接过第三方支付的小伙伴都知道,在接入第三方支付时,通常支付结果都会经过异步回调的形式,通知商户服务器。而咱们获得这些数据时通常都是同一流程的处理方式:验签 — 更新订单状态 — 给第三方支付服务器响应。 下面以支付宝和微信为例:支付宝和微信的验签方式和响应结果方式都是不同的, 而更新订单状态都是商户这边处理因此业务逻辑是同样的。框架
抽象模板类:异步
public abstract class AbstractPayNotifyTemplate {
/** * 支付异步回调处理 * * @param params 回调参数 */
public void onNotify(Map<String, String> params) {
//验证签名
final boolean sign = verifySign(params);
if (sign) {
// 给第三方支付服务器回复支付失败状态
setResponse(PayStatus.ERROR);
return;
}
//从参数获取订单编号并更新订单支付状态,为支付成功
final String orderSn = params.get("out_trade_no");
updateOrderPayStatusSuccess(orderSn);
// 给第三方支付服务器回复支付成功状态
setResponse(PayStatus.SUCCESS);
}
/** * 验签 * * @param params 回调参数 * @return 验签结果 */
protected abstract boolean verifySign(Map<String, String> params);
/** * 更新订单支付状态为支付成功 * * @param orderSn 订单编号 */
private void updateOrderPayStatusSuccess(String orderSn) {
// 根据订单编号更新订单支付状态为支付成功
}
/** * 给第三方支付返回 * * @param status 支付状态 */
protected abstract void setResponse(PayStatus status);
}
复制代码
具体模板类:ide
// 支付宝支付回调类
public class AliPayNotifyTemplate extends AbstractPayNotifyTemplate {
@Override
protected boolean verifySign(Map<String, String> params) {
// 调用支付宝验签接口, 并返回验签结果
return true;
}
@Override
protected void setResponse(PayStatus status) {
String res = Objects.equals(PayStatus.SUCCESS, status) ? "success" : "error";
// 调用 ResponseUtils 直接返回 res 字符串
}
}
// 微信支付回调类
public class WxPayNotifyTemplate extends AbstractPayNotifyTemplate {
@Override
protected boolean verifySign(Map<String, String> params) {
// 调用微信支付验签接口, 并返回验签结果
return true;
}
@Override
protected void setResponse(PayStatus status) {
String returnCode = "FAIL";
String returnMsg = "";
if (Objects.equals(PayStatus.SUCCESS, status)) {
returnCode = "SUCCESS";
returnMsg = "OK";
}
String res = String.format("<xml><return_code><![CDATA[%s]]></return_code><return_msg><![CDATA[%s]]></return_msg></xml>", returnCode, returnMsg);
// 调用 ResponseUtils 返回 res xml格式内容
}
}
复制代码
固然这只是简单例子,帮助理解模板方法模式。实际项目中还带有各类参数、异常的处理、工具类的封装,以及其余设计模式的应用。工具
提升代码复用性。将相同部分的代码放在抽象的父类中;微信支付
提升了拓展性。将不一样的代码放入不一样的子类中,经过对子类的扩展增长新的行为;
可实现一种反向控制结构,经过子类覆盖父类的钩子方法来决定某一特定步骤是否须要执行。(此处实例没有体现)
引入了抽象类,每个不一样的实现都须要一个子类来实现,致使类的个数增长,从而增长了系统实现的复杂度。