设计模式:策略+工厂+责任链解决项目中的多环境问题

608 阅读3分钟

知其然要知其所以然,探索每一个知识点背后的意义,你知道的越多,你不知道的越多,一起学习,一起进步,如果文章感觉对您有用的话,关注、收藏、点赞,有困惑的地方请评论,我们一起交流!


目标

  • 解决项目中的多环境下同一个业务场景中有非常复杂的逻辑

传统思路

  • if、else判断、再或者每一个环境一个工厂去处理各自环境的逻辑

思考

  • 如果让我们的代码更好维护呢?
  • 公共逻辑如何抽离?
  • 流程如果多的话,后面如何维护,例如审核单据:数据校验、更新数据、发送消息、发送邮件、推送第三方系统等,这么多的流程,如何做到职责单一?

解决方案(不一定是最合适的,提供一个思路)

image.png

代码如下

  • 定义上下文
/**
 * 表单基础信息
 */
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: 发送事件--------------------

总结

  • 设计模式的目的是让我们的代码更健壮、更易维护、可读性好,如果用传统的方式后期比较难以维护、而且改动一个地方会影响其他的环境,维护成本比较大。