责任链模式简化Service层代码

260 阅读2分钟

常规写法

例如我现在要更新一本书,如果按照一般的写法就是这么写

public class MyService {
    public void updateBook(Map<String, String> param) {
        // 校验param参数是否正确
        validParam(param);
        // 查询DB中book是否存在
        checkDBBook(param);
        // 更新DB
        updateDBBook(param);
    }
}

思考一下,这样写有什么好处和坏处呢?

好处:在代码量少的时候很简单,可以快速开发之后上线

坏处:如果逻辑越来越复杂,updateBook方法会调用很多其他的方法,整个类也会充斥着很多方法,之后就很难去维护

为了避免一个类写了太多的方法,做了太多的事情,其实可以将每一件事情分给不同的类,这样做可以做到的复用,想象一下,你想新写一个类,然后需要【查询DB中book是否存在】这个功能,那怎么复用呢,得先注入/新建MyService对象,再去调用他的checkDBBook方法,听起来是不是很没意思,光调一个就感觉很复杂的样子

优化写法

责任链模式可以帮你避免这些事情,思考一下,我们把需要做的事情拆分的很细,如上面的例子

  • 校验param参数是否正确
  • 查询DB中book是否存在
  • 更新DB

我们把每一件事情,都写成一个类,里面只有一个run()方法,然后谁想用,就把这个类拿过去用,这样不就可以做到解耦了吗

如下面的代码

public class MyService {
    public void updateBook(Map<String, String> param) {
        List<Class> list = new ArrayList<>();
        list.add(ValidParamWorker.class);
        list.add(CheckDBWorker.class);
        list.add(UpdateDBWorker.class);
        WorkerStart workerStart = new WorkerStart();
        workerStart.run(list);
    }
}

那么问题来了,WorkerStart类如何写?

其实也不难,我们可以给每一个Worker类实现一个接口BaseWorker,然后WorkerStart工具类只要调用BaseWorker的run方法即可

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author goku peng
 * @since 2023/7/5 23:48
 */
public class MyService {
    public static void main(String[] args) {
        List<Class<? extends BaseWorker>> list = new ArrayList<>();
        list.add(ValidParamWorker.class);
        list.add(CheckDBWorker.class);
        list.add(UpdateDBWorker.class);
        WorkerStart workerStart = new WorkerStart();
        workerStart.run(new HashMap<>(), list);
    }
}

class ValidParamWorker implements BaseWorker {

    @Override
    public void run(Map<String, Object> context) {
        System.out.println(this.getClass().getName());
    }
}

class CheckDBWorker implements BaseWorker {
    @Override
    public void run(Map<String, Object> context) {
        System.out.println(this.getClass().getName());
    }
}

class UpdateDBWorker implements BaseWorker {
    @Override
    public void run(Map<String, Object> context) {
        System.out.println(this.getClass().getName());
    }
}

class WorkerStart {
    // context在所有worker中透传,解决传递信息的问题
    public void run(Map<String, Object> context, List<Class<? extends BaseWorker>> list) {
        for (Class<? extends BaseWorker> work : list) {
            try {
                // 实际项目中可以从spring中拿到实例
                BaseWorker baseWorker = work.newInstance();
                baseWorker.run(context);
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }
}

interface BaseWorker {
    void run(Map<String, Object> context);
}

通过这种写法,可以很好的解耦,只需要把每一件事拆分的很细,service层自己编排即可