业务解耦,以注册机制,实现多条业务线的通信回调问题(主要作用于一个项目内使用)

一:解决的业务问题:

    业务A的处理到一个节点,需要不同情况需要调用或回调不同的多个平级业务。一般情况下,我们会在业务A的主表等中有一个业务类型,通过业务类型判断应该调用或者回调目标业务。但是这种处理是一旦有新的业务需要业务线A去调用或回调其他业务线,不仅需要其他的业务线提供方法,还需要业务线A增加分支判断去调用,会造成业务A中的代码中有大量的跟本身业务无关的其他业务的服务层等的注入,这样就违背了职责单一原则,代码耦合性非常高,维护难度大。

二:解决方案

     对于本文的业务问题,提供一种方案是单例模式+策略模式来处理。

     单例模式:作用保证全局有唯一的一个工厂。

     策略模式:即向工厂添加的不同的业务线的具体业务实现,通过key实现具体业务的调用

两种方式优略对比如下,单例模式+策略模式 的使用只要类型的静态类做好维护,对于可读性的影响基本没有。

   三:代码实现   

     1,静态类

/**
 * 册回调 指定类型的业务的类型指定 每个类型只能使用一次
 **/
public class BussTypeConstant {
    /**
     * 业务类型
     */
    public static final String BUSS_TYPE1="buss_type1";
}

  2,处理类实体

@Schema(description = "业务回调实体类")
@Data
public class BussInfo implements Serializable {
	private static final long serialVersionUID = 1L;
	@Schema(description ="业务id")
	private String bussId;
	/**
     * 这里列举的是返回给要调用的业务的结果 如果是其他处理可自行调整,比如用json
	 * REFUSE 任务结束 流程拒绝
	 * SUCCESS 任务结束 整个流程完成
	 */
	@Schema(description = "NO_PASS 不通过,SUCCESS 通过")
	private BussStatus bussStatus;
}

   3,枚举类

@Getter
public enum BussStatus {

    NO_PASS("未通过"),
    SUCCESS("通过");

    private String name;

    BussStatus(String name) {
        this.name = name;
    }
}

4,核心代码

//
public interface MyFunction<T, R> {
        R apply(T t);
}




@Component
public class BussInfoHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(BussInfoHandler.class);
    private final Map<String,List<MyFunction<BussInfo,Boolean>>> bussIdHandler;
    public BussInfoHandler() {
        this.bussIdHandler = new HashMap<>();
    }
    public void addBussHandler(String bussTp,MyFunction<BussInfo,Boolean> handler){
        List<MyFunction<BussInfo,Boolean>> handlers = bussIdHandler.get(bussTp);
        if(CollectionUtils.isEmpty(handlers)){
            bussIdHandler.put(bussTp,new ArrayList<MyFunction<BussInfo,Boolean>>());
        }
        bussIdHandler.get(bussTp).add(handler);
    }
    public boolean handlerBuss(String bussTp,BussInfo bussInfo){
        List<MyFunction<BussInfo,Boolean>> handlers = bussIdHandler.get(bussTp);
        for(MyFunction<BussInfo,Boolean> handler : handlers){
            if(Objects.nonNull(handler)){
                return handler.apply(bussInfo);
            }else{
                LOGGER.warn("not found for bussTp"+bussTp);
                return false;
            }
        }
        return false;
    }
}

5,任务线代码的业务注册

@Autowired
    BussInfoHandler bussInfoHandler;
    @PostConstruct
    private void registerBussHandler() {
        bussInfoHandler.addBussHandler(BussTypeConstant.BUSS_TYPE1, new MyFunction<BussInfo, Boolean>() {
            @Override
            public Boolean apply(BussInfo bussInfo) {
                String id = bussInfo.getBussId(); //对应业务的id
                if (StrUtil.equals(BussStatus.SUCCESS.getName(), bussInfo.getBussStatus().getName())) {
                   //通过的处理
                } else {
                  //不通过的处理
                }
                return true; //根据实际情况处理
            }
        });
    }

6.业务A调用

@Autowired
	BussInfoHandler bussInfoHandler;



BussInfo bussInfo =new BussInfo();
bussInfo.setBussId(issue.getBussId());
bussInfo.setBussStatus(BussStatus.SUCCESS);
				//回调业务
bussInfoHandler.handlerBuss("主业务中取出的类型,就是你注册时放的类型(本例BussTypeConstant.BUSS_TYPE1),看自己怎么安排了",bussInfo);

以上就是全部的代码实现

下面补充一些原理讲解

  1. 单例模式(Singleton):虽然没有明确地使用单例模式,但 bussIdHandler 是一个静态的 Map,这意味着在整个应用程序中只有一个 bussIdHandler 实例。这可以看作是单例模式的一种变体,因为它是全局唯一的。
  2. 策略模式(Strategy)MyFunction<BussInfo,Boolean> 是一个函数式接口,它定义了处理 BussInfo 的策略。通过 addBussHandler 方法,可以向处理器列表中添加不同的处理策略。在 handlerBuss 方法中,根据 bussTp 选择一个处理策略来处理 BussInfo。这是策略模式的一个典型应用,即根据情况选择不同的算法或行为。
  3. @PostConstruct是Java自带的注解,用于在项目启动或Servlet初始化时执行特定方法。从Java EE5规范开始,Servlet中增加了两个影响Servlet生命周期的注解,@PostConstruct和@PreDestroy,这两个注解被用来修饰一个非静态的void()方法。

    在Spring框架中,@PostConstruct注解的方法会在依赖关系注入完成后执行,以执行任何初始化操作。此方法必须在将类放入服务之前调用,即使类没有请求注入任何资源,用 @PostConstruct 注解的方法也必须被调用。

    被@PostConstruct注解的方法会在服务器加载Servle的时候运行,并且只会被服务器执行一次。这个注解常用于加载一些缓存数据、初始化类等场景

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值