前言
模板方法是应用相对较为广泛的一个设计模式。以Java继承特性为基础实现,即在抽象父类(模板)中规定目标算法框架/步骤,在子类中实现某些特定步骤的逻辑。在抽象模板中通常会定义两类方法:一类是模板方法,可以有一个或多个,用于定义算法框架/步骤,并且也可定义一些钩子方法使模板更加灵活;另一类是基本方法,由子类实现其中的逻辑,被模板方法调用。类图如下:
模板方法模式实践
1 基础类
1.1 BaseDTO
public class BaseDTO implements Serializable {
}
1.2 Result
public class Result {
private String code; //码值
private String msg; //提示信息
private Object data; //数据
public void setCode(String code) {
this.code = code;
}
public void setMsg(String msg) {
this.msg = msg;
}
public void setData(Object data) {
this.data = data;
}
public String getCode() {
return code;
}
public String getMsg() {
return msg;
}
public Object getData() {
return data;
}
}
1.3 CustomerInfoDTO
@Data
@NoArgsConstructor
public class CustomerInfoDTO extends BaseDTO {
private String custId; //客户编号
private String custNm; //客户名称
private String ctfTp; //证件类型
private String cftNo; //证件编号
//get、set方法...
}
2 抽象模板角色
public abstract class AbstractTemplateMethod<I extends BaseDTO> {
//保存,提供给外部调用,不允许被重写
public final Result save(I params){
Result result = null;
if(this.isValidate()){
result = this.doCheck();
if(result != null && "succ".equals(result.getCode())){
boolean saveFlag = this.saveData(params);
result.setCode(saveFlag ? "succ":"fail");
}
}else{
result = new Result();
boolean saveFlag = this.saveData(params);
result.setCode(saveFlag ? "succ":"fail");
}
return result;
}
//数据保存逻辑
protected abstract boolean saveData(I params);
//保存前校验
protected abstract Result doCheck();
//是否执行保存前校验方法,钩子
protected boolean isValidate(){
return false;
}
}
3 具体子类角色
public class ConcreteMethod extends AbstractTemplateMethod<CustomerInfoDTO> {
@Override
protected boolean saveData(CustomerInfoDTO params) {
//执行保存逻辑
//...
return true;
}
@Override
protected Result doCheck() {
Result result = new Result();
result.setCode("succ");
result.setMsg("校验通过!");
return result;
}
//是否执行保存前校验方法,钩子
protected boolean isValidate(){
return true;
}
}
4 客户端调用/测试
public class ClientTest {
public static void main(String[] args){
AbstractTemplateMethod templateMethod = new ConcreteMethod();
templateMethod.save(new CustomerInfoDTO());
}
}
总结
- 模板方法模式是将不变的部分封装到父类中,可变的部分由子类实现,但是在复杂点的项目/功能中这样会增加代码阅读难度;
- 项目重构时模板方法模式经常会被用到,会将相同的部分抽象到父类中,部分由子类实现的方法可用钩子方法控制其行为;
- 模板类中提供了外部访问接口,通常被 final 修饰防止被子类重写。