知其然要知其所以然,探索每一个知识点背后的意义,你知道的越多,你不知道的越多,一起学习,一起进步,如果文章感觉对您有用的话,关注、收藏、点赞,有困惑的地方请评论,我们一起交流!
目标
- 解决项目中的多环境下同一个业务场景中有非常复杂的逻辑
传统思路
- if、else判断、再或者每一个环境一个工厂去处理各自环境的逻辑
思考
- 如果让我们的代码更好维护呢?
- 公共逻辑如何抽离?
- 流程如果多的话,后面如何维护,例如审核单据:数据校验、更新数据、发送消息、发送邮件、推送第三方系统等,这么多的流程,如何做到职责单一?
解决方案(不一定是最合适的,提供一个思路)
代码如下
- 定义上下文
/**
* 表单基础信息
*/
public class FormBaseContext {
}
- 定义接口
/**
* 业务 写接口
*
* @author mac
*/
public interface BizFormBaseService<T extends FormBaseContext> {
/**
* 提交
*
* @param context
* @return
*/
Response submit(T context);
/**
* 保存
*
* @param context
* @return
*/
Response save(T context);
/**
* 获取详情
*
* @param orderNo
* @return
*/
Response<T> getDetail(String orderNo);
}
- 定义顺序
/**
* 业务保存信息
*/
public interface BizSaveInformationService {
/**
* 执行排序
* @return
*/
Integer getOrder();
/**
* 获取执行环境
* @return
*/
String getEnvironment();
/**
* 执行核心逻辑
* @param context
*
*/
void handle(TiFormBaseContext context);
}
- 定义抽象类
public abstract class AbsBizFormBaseServiceImpl implements BizFormBaseService<TiFormBaseContext> {
public abstract List<BizSaveInformationService> getTiSaveInformationService();
@Override
public Response submit(TiFormBaseContext context) {
for (BizSaveInformationService bizSaveInformationService : getTiSaveInformationService()) {
bizSaveInformationService.handle(context);
}
return new Response();
}
@Override
public Response save(TiFormBaseContext context) {
return null;
}
@Override
public Response<TiFormBaseContext> getDetail(String orderNo) {
return null;
}
}
- 定义常量
@Data
public class Constant {
public static final String DEFAULT_ENV = "default";
}
- 定义环境
@Slf4j
@Service
public class BizAFormBaseServiceImpl extends AbsBizFormBaseServiceImpl implements BizFormBaseService<TiFormBaseContext> {
@Autowired
private FormBaseFactory formBaseFactory;
private static final String environment = "A";
@Autowired
private List<BizSaveInformationService> bizSaveInformationServiceList;
@Override
public List<BizSaveInformationService> getTiSaveInformationService() {
return bizSaveInformationServiceList;
}
@PostConstruct
public void init() {
formBaseFactory.registerTiFormWriteService(environment, this);
Map<Integer, BizSaveInformationService> tiSaveInformationServiceMap = bizSaveInformationServiceList.stream()
.filter(service -> Arrays.asList(Constant.DEFAULT_ENV, environment).contains(service.getEnvironment()))
.collect(Collectors.toMap(BizSaveInformationService::getOrder, Function.identity(),
((tiSaveInformationService, tiSaveInformationService2) ->
environment.equals(tiSaveInformationService.getEnvironment()) ?
tiSaveInformationService : tiSaveInformationService2)));
bizSaveInformationServiceList = new ArrayList<>(tiSaveInformationServiceMap.values()).stream()
.sorted(Comparator.comparing(BizSaveInformationService::getOrder)).collect(Collectors.toList());
}
}
@Slf4j
@Service
public class BizBFormBaseServiceImpl extends AbsBizFormBaseServiceImpl implements BizFormBaseService<TiFormBaseContext> {
@Autowired
private FormBaseFactory formBaseFactory;
private static final String environment = "B";
@Autowired
private List<BizSaveInformationService> bizSaveInformationServiceList;
@Override
public List<BizSaveInformationService> getTiSaveInformationService() {
return bizSaveInformationServiceList;
}
@PostConstruct
public void init() {
formBaseFactory.registerTiFormWriteService(environment, this);
Map<Integer, BizSaveInformationService> tiSaveInformationServiceMap = bizSaveInformationServiceList.stream()
.filter(service -> Arrays.asList(Constant.DEFAULT_ENV, environment).contains(service.getEnvironment()))
.collect(Collectors.toMap(BizSaveInformationService::getOrder, Function.identity(),
((tiSaveInformationService, tiSaveInformationService2) ->
environment.equals(tiSaveInformationService.getEnvironment()) ?
tiSaveInformationService : tiSaveInformationService2)));
bizSaveInformationServiceList = new ArrayList<>(tiSaveInformationServiceMap.values()).stream()
.sorted(Comparator.comparing(BizSaveInformationService::getOrder)).collect(Collectors.toList()); }
}
@Slf4j
@Service
public class BizCFormBaseServiceImpl extends AbsBizFormBaseServiceImpl implements BizFormBaseService<TiFormBaseContext> {
@Autowired
private FormBaseFactory formBaseFactory;
private static final String environment = "C";
@Autowired
private List<BizSaveInformationService> bizSaveInformationServiceList;
@Override
public List<BizSaveInformationService> getTiSaveInformationService() {
return bizSaveInformationServiceList;
}
@PostConstruct
public void init() {
formBaseFactory.registerTiFormWriteService(environment, this);
Map<Integer, BizSaveInformationService> tiSaveInformationServiceMap = bizSaveInformationServiceList.stream()
.filter(service -> Arrays.asList(Constant.DEFAULT_ENV, environment).contains(service.getEnvironment()))
.collect(Collectors.toMap(BizSaveInformationService::getOrder, Function.identity(),
((tiSaveInformationService, tiSaveInformationService2) ->
environment.equals(tiSaveInformationService.getEnvironment()) ?
tiSaveInformationService : tiSaveInformationService2)));
bizSaveInformationServiceList = new ArrayList<>(tiSaveInformationServiceMap.values()).stream()
.sorted(Comparator.comparing(BizSaveInformationService::getOrder)).collect(Collectors.toList()); }
}
- 定义顺序
public enum BizSaveFormOrderEnum {
DEFAULT_SAVE_FORM_CHECK(10,"保存信息校验"),
DEFAULT_SAVE_BASE_FORM(20,"保存基本信息"),
A_SAVE_BASE_FORM(20,"A环境保存基本信息(差异化)"),
DEFAULT_C_SAVE_FAULT_INFO_FORM(25,"保存故障基本信息-C环境"),
DEFAULT_SAVE_SEND_EVENT_FORM(30,"保存基本信息发送事件"),
;
private final Integer order;
private final String desc;
BizSaveFormOrderEnum(Integer order, String desc) {
this.order = order;
this.desc = desc;
}
public Integer getOrder() {
return order;
}
public String getDesc() {
return desc;
}
}
- 定义执行类
@Service
@Slf4j
public class BizASaveBaseServiceImpl implements BizSaveInformationService {
@Override
public Integer getOrder() {
return BizSaveFormOrderEnum.A_SAVE_BASE_FORM.getOrder();
}
@Override
public String getEnvironment() {
return "A";
}
@Override
public void handle(TiFormBaseContext context) {
log.info("A环境保存基本信息逻辑--------------------");
}
}
@Service
@Slf4j
public class BizCSaveFaultInfoServiceImpl implements BizSaveInformationService {
@Override
public Integer getOrder() {
return BizSaveFormOrderEnum.DEFAULT_C_SAVE_FAULT_INFO_FORM.getOrder();
}
@Override
public String getEnvironment() {
return "C";
}
@Override
public void handle(TiFormBaseContext context) {
log.info("C环境保存故障信息--------------");
}
}
@Service
@Slf4j
public class BizSaveBaseinfoServiceImpl implements BizSaveInformationService {
@Override
public Integer getOrder() {
return BizSaveFormOrderEnum.DEFAULT_SAVE_BASE_FORM.getOrder();
}
@Override
public String getEnvironment() {
return Constant.DEFAULT_ENV;
}
@Override
public void handle(TiFormBaseContext context) {
log.info("保存基本信息逻辑--------------------");
}
}
@Service
@Slf4j
public class BizSaveFormSendEventServiceImpl implements BizSaveInformationService {
@Override
public Integer getOrder() {
return BizSaveFormOrderEnum.DEFAULT_SAVE_SEND_EVENT_FORM.getOrder();
}
@Override
public String getEnvironment() {
return Constant.DEFAULT_ENV;
}
@Override
public void handle(TiFormBaseContext context) {
log.info("发送事件--------------------");
}
}
@Service
@Slf4j
public class BizSaveInformationCheckServiceImpl implements BizSaveInformationService {
@Override
public Integer getOrder() {
return BizSaveFormOrderEnum.DEFAULT_SAVE_FORM_CHECK.getOrder();
}
@Override
public String getEnvironment() {
return Constant.DEFAULT_ENV;
}
@Override
public void handle(TiFormBaseContext context) {
log.info("check逻辑--------------------");
}
}
- 执行
@PostMapping("/submit")
public void submit() {
BizFormBaseService a = formBaseFactory.getTiFormWriteService("A");
FormBaseContext context = new FormBaseContext();
a.submit(context);
}
-执行完就回打印以下日志:
INFO [2025-03-27 02:21:56,323] [http-nio-8080-exec-2] org.demo.service.BizSaveInformationCheckServiceImpl: check逻辑--------------------
INFO [2025-03-27 02:21:56,323] [http-nio-8080-exec-2] org.demo.service.BizASaveBaseServiceImpl: A环境保存基本信息逻辑--------------------
INFO [2025-03-27 02:21:56,323] [http-nio-8080-exec-2] org.demo.service.BizSaveFormSendEventServiceImpl: 发送事件--------------------
总结
- 设计模式的目的是让我们的代码更健壮、更易维护、可读性好,如果用传统的方式后期比较难以维护、而且改动一个地方会影响其他的环境,维护成本比较大。