代码改造:设计模式之责任链

前言


最近负责了一个相对大点的项目,在开发的时候一把梭哈,最近在做代码优化(个人习惯是开发时把逻辑快速搞完,很多实现方式在设计阶段已经拍板,不会有太大问题,然后等开发完后再开始做精修)

发现了一个很长的逻辑,有190行,包括注释、换行还有代码,那么如何进行代码优化呢?

灵感


在看阿里的一个设计方案的时候,找到一个灵感,就是凑单很多数据都是别人的,互相不影响,只是将数据进行拼接,采用了责任链的形式,就是每个处理器都能处理到,然后进行加工,最后得到一个结果。

将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求。将这些接收对象串成一条链,并沿着这条链传递这个请求,直到链上的某个接收对象能够处理它为止。

责任链


第一次接触责任链是在网关层,globalFilter,网关会有filter链条,每个拦截器会有自己的逻辑,比如说限流、权限、参数打印等等逻辑,如果其中一个处理器不通过则中断请求。

我们这个功能有所不同的是:并不是其中一个处理器不通过就中断,而是没有就跳过处理,进入下一个处理器进行加工,直到所有的处理器加工完成整个处理流程。有点像车间流水线,一个环节装一点,然后拼接成一辆车。

实践

业务背景

一个定时器处理拉取数据的逻辑,设计到4个模块

定义处理器

有处理方法,然后有另外一个标识当前处理器是什么类型

/**
 * 定时器处理器
 */
public interface Processor {

    /**
     * 加工处理过程
     *
     * @param exchange
     */
    void process(ChainExchange exchange);

    /**
     * 类型
     *
     * @return
     */
    ProcessorType type();

}
复制代码

链条中上下文

这里定义的是传递数据,比如说最终加工成一辆车,就是传递一整车的数据,车顶、轮毂......

/**
 * 链条交换数据
 */
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ChainExchange {

/**
* 上下文传递的参数
**/
    private xx xx;

}
复制代码

处理器枚举

@Getter
@AllArgsConstructor
public enum ProcessorType {

    /**
     * 处理器枚举值
     */
    
    xx("xx处理器");

    /**
     * 状态
     */
    private String message;

}
复制代码

定义相应处理器

这里定义链条中某个处理器的处理逻辑,还有标识

/**
 * 账单附件处理器
 */
@Component
public class xxProcessor implements Processor {

    @Override
    public void process(ChainExchange exchange) {
        
    }

    @Override
    public ProcessorType type() {
        return ProcessorType.xx;
    }

}
复制代码

装订整个链条

/**
 * 处理链条汇总
 */
@Component
public class ProcessorChain implements InitializingBean {

    @Resource
    private List<Processor> formFacadeList;

    /**
     * 处理器链条
     */
    private final List<Processor> processorList = new ArrayList<>();

    private void init() {
        //初始化处理链条 xx->xx->xx
        processorList.add(formFacadeList.stream().filter(it -> ProcessorType.BILL.equals(it.type())).findFirst().get());
    }

    /**
     * 处理数据
     */
    public void handleData(xx xx) {

        //处理节点下标
        int index = 0;

        //上下文传递内容
        ChainExchange exchange = ChainExchange.builder().build();

        while (index < processorList.size()) {
            Processor processor = processorList.get(index);
            processor.process(exchange);

            index++;
        }
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        init();
    }
}
复制代码

到这里所有处理器的链条装订完毕,我们只需执行这整个链条即可,等待流水线的加工完毕。

责任链好处


从一个方法190行代码,到拆分成4个类,每个类的逻辑都是一个模块的,这样代码的可读性是提高了,然后扩展性比较好的,比如说某个模块需要改造,可以避免代码的遗漏。

就像车顶加工流程需要优化,我们只改车顶加工节点的逻辑。

image.png

猜你喜欢

转载自juejin.im/post/7129792302142193695