模板方法在实际工作中的应用案例记录
本文介绍模板方法在实际工作中应用的一个 列子,该列子主要基于银行的计息模块设计 ,使得计息方法模板化,但每个产品又能按照各自独有的业务执行。调用方只关心入口调用,不关心内部转换,增加接口扩展性。
在阅读该文章之前我们先了解Spring提供的InitializingBean
接口:
一、InitializingBean
简介:
InitializingBean
是Spring提供的一个拓展性接口,InitializingBean
接口为bean
提供了属性初始化后的处理方法,它只有一个afterPropertiesSet
方法,凡是继承该接口的类,在bean
的属性初始化后都会执行afterPropertiesSet()
方法,注入该bean
。
二、具体实现过程如下:
定义输入、输出参数Dto:
package com.example.biz.dto;
public class CalInDto {
// 计算方式
private String calWay;
// 模板方法
private String methodWay;
// 账户
private String custAcct;
// 其余参数...
}
package com.example.biz.dto;
public class CalOutDto {
// 流水号
private String sysSeqNo;
// 账户
private String custAcct;
// 其余参数...
}
定义计息模板方法接口:
package com.example.biz.factory;
import com.example.biz.dto.CalInDto;
import com.example.biz.dto.CalOutDto;
import org.springframework.beans.factory.InitializingBean;
/**
* 模板方法接口:用于定义共有的模板方法
*/
public interface BizCalTemplateMethod extends InitializingBean {
// 初始化
CalOutDto initTable(CalInDto calInDto);
// 试算
CalOutDto tryCalWay(CalInDto calInDto);
}
定义模板方法抽象类,实现模板方法接口:
package com.example.biz.factory;
import com.example.biz.dto.CalInDto;
import com.example.biz.dto.CalOutDto;
// 模板方法抽象类,将通用的、固定的步骤放在抽象类中实现,实现代码复用
abstract class BizCalAbstractTemplate implements BizCalTemplateMethod{
@Override
public CalOutDto tryCalWay(CalInDto calInDto) {
return null;
}
@Override
public CalOutDto initTable(CalInDto calInDto) {
return null;
}
}
定义工厂方法类,提供给调用方调用:
package com.example.biz.factory;
import com.example.biz.dto.CalInDto;
import com.example.biz.dto.CalOutDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.util.HashMap;
import java.util.Map;
@Component
public class BizCalFactory {
private static final Logger logger = LoggerFactory.getLogger(BizCalFactory.class);
// 定义初始化Map
private static Map<String,BizCalTemplateMethod> bizMap = new HashMap<>();
public static void register(String key,BizCalTemplateMethod templateMethodHandler) {
if (StringUtils.isEmpty(key) && StringUtils.isEmpty(templateMethodHandler)) {
logger.error("初始化工厂组件失败:key:{},value:{}",key,templateMethodHandler);
return;
}
bizMap.put(key, templateMethodHandler);
}
public static BizCalTemplateMethod getInvokeHandler(String key) {
return bizMap.get(key);
}
// 提供给外层调用的工厂入口
public CalOutDto dealBizCal(CalInDto calInDto) {
// 根据配置类注册的计算方式获取对应的实现类
BizCalTemplateMethod bizCalTemplateMethod = getInvokeHandler(calInDto.getCalWay());
if (StringUtils.isEmpty(bizCalTemplateMethod)) {
logger.error("获取实现类失败");
}
CalOutDto calOutDto = caseProcessMethod(bizCalTemplateMethod,calInDto);
return calOutDto;
}
// 内部具体调用流程,根据入参实现具体模板方法的调用
private CalOutDto caseProcessMethod(BizCalTemplateMethod bizCalTemplateMethod,CalInDto calInDto) {
CalOutDto calOutDto = new CalOutDto();
switch (calInDto.getMethodWay()) {
case "1":
calOutDto = bizCalTemplateMethod.initTable(calInDto);
break;
case "2":
calOutDto = bizCalTemplateMethod.tryCalWay(calInDto);
break;
default:
throw new RuntimeException("模板方法未找到,传入参数有误,请检查");
// break;
}
return calOutDto;
}
}
具体实现类一,继承抽象类,重写模板方法:
package com.example.biz.factory;
import com.example.biz.dto.CalInDto;
import com.example.biz.dto.CalOutDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
public class BizDpRule extends BizCalAbstractTemplate {
private static final Logger logger = LoggerFactory.getLogger(BizDpRule.class);
@Override
public CalOutDto tryCalWay(CalInDto calInDto) {
CalOutDto calOutDto = new CalOutDto();
logger.info("BizDpRule::tryCalWay");
calOutDto.setSysSeqNo("9999999");
// 具体业务实现...
return calOutDto;
}
@Override
public CalOutDto initTable(CalInDto calInDto) {
CalOutDto calOutDto = new CalOutDto();
logger.info("BizDpRule::initTable");
calOutDto.setSysSeqNo("8888888");
// 具体业务实现...
return calOutDto;
}
// 实现afterPropertiesSet
@Override
public void afterPropertiesSet() throws Exception {
BizCalFactory.register("100",this);
}
}
具体实现类二:
package com.example.biz.factory;
import com.example.biz.dto.CalInDto;
import com.example.biz.dto.CalOutDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
public class BizNtcRule extends BizCalAbstractTemplate {
private static final Logger logger = LoggerFactory.getLogger(BizNtcRule.class);
@Override
public CalOutDto tryCalWay(CalInDto calInDto) {
CalOutDto calOutDto = new CalOutDto();
logger.info("BizNtcRule::tryCalWay");
calOutDto.setSysSeqNo("11111111");
// 具体业务实现...
return calOutDto;
}
@Override
public CalOutDto initTable(CalInDto calInDto) {
CalOutDto calOutDto = new CalOutDto();
logger.info("BizNtcRule::tryCalWay");
calOutDto.setSysSeqNo("2222222");
// 具体业务实现...
return calOutDto;
}
@Override
public void afterPropertiesSet() throws Exception {
BizCalFactory.register("200",this);
}
}
调用实现:
package com.example.bootstudy;
import com.alibaba.fastjson.JSONObject;
import com.example.biz.dto.CalInDto;
import com.example.biz.dto.CalOutDto;
import com.example.biz.factory.BizCalFactory;
import com.example.biz.lectCode.StudyLetCode;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class BootStudyApplicationTests {
@Test
void contextLoads() {
CalInDto calInDto = new CalInDto();
// 该参数可根据具体产品参数配置
calInDto.setCalWay("100");
// 具体调用方法
calInDto.setMethodWay("1");
// 调用入口工厂
BizCalFactory bizCalFactory = new BizCalFactory();
CalOutDto cal = bizCalFactory.dealBizCal(calInDto);
System.out.println(JSONObject.toJSONString(cal));
}
}
运行结果
本文主要记录工作中使用到的工厂模式加模板方法的使用,希望对你有所帮助。