概念
模板方法模式属于行为型模式。它定义了一个操作中算法的骨架, 并将一些步骤延迟到子类中。模板方法模式可以让子类在不改变算法整体结构的情况下,重新定义算法中的某些步骤。
模板方法模式的优点如下:
- 方法分为不变部分、可变部分。不变部分的算法封装在父类中实现,可变部分算法由子类继承实现,便于在子类中继续扩展。这符合开闭原则。
- 在父类中提取了公共的部分代码,便于代码复用。
缺点如下:
- 对每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象。
示例
public abstract class AbstractRequestService<T> {
Map<String, String> params;
public AbstractRequestService() {
params = Maps.newHashMap();
}
/*被子类重写的方法*/
protected abstract void initParams(Map<String, String> params);
protected abstract T parse(JSON jsonData);
/*主方法,实现对本类其它方法的调用*/
public T request(Integer id) {
// 获取Client对象
Client client = ApplicationContextHolder.getBean(Client.class);
initParams(this.params);
return parse(client.request(this.params));
}
}
public class RequestService {
private List<PersonDTO> getInfoById(Integer id) {
/*匿名内部类形式实现子类*/
AbstractRequestService<List<PersonDTO>> abstractService = new AbstractRequestService<List<PersonDTO>>() {
@Override
protected void initParams(Map<String, String> params) {
// 账户 ID
params.put("id", "" + id);
}
@Override
protected List<PersonDTO> parse(JSON jsonData) {
return ((JSONObject) jsonData).getJSONArray("list").toJavaList(PersonDTO.class).;
}
};
return abstractService .request(id);
}
public Map<Long, Integer> getMapById(Integer id) {
AbstractRequestService<Map<Long, Integer>> abstractService = new AbstractRequestService<Map<Long, Integer>>() {
@Override
protected void initParams(Map<String, String> params) {
params.put("client_id", id + "");
}
@Override
protected Map<Long, Integer> parse(JSON jsonData) {
Map<Long, Integer> map = new HashMap<>();
//.....
return map;
}
};
return abstractService .request(id);
}
public static void main(String[] args) {
RequestService service= new RequestService();
service.getInfoById(1);
}
}
模板方法模式在spring中的应用
AbstractHandlerMapping
AbstractHandlerMapping 是实现HandlerMapping接口的一个抽象类。支持排序、默认处理程序、处理程序拦截器,包括由路径模式映射的处理程序拦截器。它实现了获得请求对应的处理器和拦截器们的骨架逻辑,而暴露 #getHandlerInternal(HttpServletRequest request) 抽象方法,交由子类(AbstractUrlHandlerMapping 、AbstractHandlerMethodMapping )实现。
- AbstractUrlHandlerMapping,基于url匹配。
- AbstractHandlerMethodMapping,基于 Method 进行匹配,如@RequestMapping
@Nullable
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
Object handler = this.getHandlerInternal(request);
//将请求与handler封装成一个处理链返回
...
}
AbstractPlatformTransactionManager
AbstractPlatformTransactionManager抽象类实现了Spring事务的标准流程,然后为每个ORM框架提供实现类。其子类DataSourceTransactionManager是我们使用较多的JDBC单数据源事务管理器,应用中需要使用Spring事务时,以Bean的方式注册相应PlatformTransactionManager实现类在Spring容器中即可。
// 通过getTransaction()获取事务,具体实现内部doGetTransaction()、doBegin交由子类处理开启事务。
public final TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
Object transaction = doGetTransaction();
....
try {
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
DefaultTransactionStatus status = newTransactionStatus(
definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
doBegin(transaction, definition);
prepareSynchronization(status, definition);
return status;
}
....
}
//在通过commit()提交事务时,具体实现内部调用doCommit()方法完成事务提交或doRollback完成事务回滚。
public final void commit(TransactionStatus status) throws TransactionException {
...
if()processRollback(defStatus);
processCommit(defStatus);
}