一、概述
定义一个操作中的算法的骨架,将一些步骤延迟到子类中。 TemplateMethod使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。
二、适用性
1.一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。
2.各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。 首先识别现有代码中的不同之处,并且将不同之处分离为新的操作。 最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。
3.控制子类扩展。
三、参与者
1.AbstractClass 定义抽象的原语操作(primitive operation),具体的子类将重新定义它们以实现一个算法的各个步骤。 实现一个模板方法,定义一个算法的骨架。 该模板方法不仅调用原语操作,也调用定义在AbstractClass或其他对象中的操作。
2.ConcreteClass 实现原语操作以完成算法中与特定子类相关的步骤。
四、类图
五、示例
AbstractClass
public abstract class Template {
public abstract void print();
public void update() {
System.out.println("开始打印");
for (int i = 0; i < 3; i++) {
print();
}
}
}
ConcreteClass
public class TemplateConcrete extends Template{
@Override
public void print() {
System.out.println("这是TemplateConcrete类的实现");
}
}
自测
@Test
public void testTemplate() {
Template temp = new TemplateConcrete();
temp.update();
}
自测结果
Connected to the target VM, address: '127.0.0.1:12824', transport: 'socket'
开始打印
这是TemplateConcrete类的实现
这是TemplateConcrete类的实现
这是TemplateConcrete类的实现
Disconnected from the target VM, address: '127.0.0.1:12824', transport: 'socket'
六、实践
封装
/**
* @author lyonardo
* @Description
* @createTime 2022年09月24日 14:35:00
*/
@Slf4j
public abstract class FxBaseListenerAbstract<T, E> {
/* private final MongoService mongoService = SpringUtil.getBean(MongoService.class);
public E pick(String dataId, Class<E> var2){
return mongoService.findById(dataId,var2);
}*/
public E pickFx(BaseObject baseBO, String url, Class<E> var2){
return doSomething...;
}
protected abstract T getConverter(E resource);
public void dataHandle(String dataObjectApiName, String dataId , String url, IService<T> iService, LambdaUpdateWrapper<T> updateWrapper, Class<E> var2){
return doSomething();
}
public String pickFxResult(BaseBO baseBO, String url){
return doSomething...;
}
}
使用
/**
* @author lyonardo
* @Description 客户监听订阅事件
* @createTime 2022年09月20日 09:38:00
*/
@Slf4j
@Service
public class XxAccountListener extends XxBaseListenerAbstract<TxxAccountInfoDO, FxxAccountObjBO> {
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public void handle(String eventType, String dataId) {
return doSomething...;
}
@Override
protected TxxAccountInfoDO getConverter(FxxAccountObjBOresource) {
return doSomething...;
}
}
通过对核心方法的抽取处理以及公共抽象方法的封装,使用工厂模式、单例模式、模板方法等,让团队其他开发在进行几十上百个业务对象进行全量、增量、对接开发时,只需要关注和实现业务对象的handle方法和对象转换处理getConverter,不用关注具体的细节,不仅大大减少了代码重复量和工作量,也大大降低了易错率。