我们来看一个常见的业务场景,下订单。下订单接口,基本的逻辑,一般有参数非空校验、安全校验、黑名单校验、规则拦截等等。很多伙伴会使用异常来实现:
- public class Order {
-
- public void checkNullParam(Object param){
- //参数非空校验
- throw new RuntimeException();
- }
- public void checkSecurity(){
- //安全校验
- throw new RuntimeException();
- }
- public void checkBackList(){
- //黑名单校验
- throw new RuntimeException();
- }
- public void checkRule(){
- //规则拦截
- throw new RuntimeException();
- }
-
- public static void main(String[] args) {
- Order order = new Order();
- try{
- order.checkNullParam();
- order.checkSecurity ();
- order.checkBackList();
- order.checkRule();
- System.out.println("order success");
- }catch (RuntimeException e){
- System.out.println("order fail");
- }
- }
- }
这段代码使用了异常来做逻辑条件判断,如果后续逻辑越来越复杂的话,会出现一些问题:如异常只能返回异常信息,不能返回更多的字段,这时候需要自定义异常类。
并且,阿里开发手册规定:禁止用异常做逻辑判断。
【强制】 异常不要用来做流程控制,条件控制。 说明:异常设计的初衷是解决程序运行中的各种意外情况,且异常的处理效率比条件判断方式要低很多。
如何优化这段代码呢?可以考虑责任链模式
当你想要让一个以上的对象有机会能够处理某个请求的时候,就使用责任链模式。
责任链模式为请求创建了一个接收者对象的链。执行链上有多个对象节点,每个对象节点都有机会(条件匹配)处理请求事务,如果某个对象节点处理完了,就可以根据实际业务需求传递给下一个节点继续处理或者返回处理完毕。这种模式将根据请求的类型,对请求的发送者和接收者进行解耦。
责任链模式实际上是一种处理请求的模式,它让多个处理器(对象节点)都有机会处理该请求,直到其中某个处理成功为止。责任链模式把多个处理器串成链,然后让请求在链上传递 :

责任链模式怎么使用呢?
1.一个接口或者抽象类
这个接口或者抽象类,需要:
- public abstract class AbstractHandler {
-
- //责任链中的下一个对象
- private AbstractHandler nextHandler;
-
- /**
- * 责任链的下一个对象
- */
- public void setNextHandler(AbstractHandler nextHandler){
- this.nextHandler = nextHandler;
- }
-
- /**
- * 具体参数拦截逻辑,给子类去实现
- */
- public void filter(Request request, Response response) { //通用方法 递归调用
- doFilter(request, response);
- if (getNextHandler() != null) {
- getNextHandler().filter(request, response);
- }
- }
-
- public AbstractHandler getNextHandler() {
- return nextHandler;
- }
-
- abstract void doFilter(Request filterRequest, Response response); //子类去实现具体的逻辑
-
- }
2.每个对象差异化处理
责任链上,每个对象的差异化处理,如本节的业务场景,就有参数校验对象、安全校验对象、黑名单校验对象、规则拦截对象。
- /**
- * 参数校验对象
- **/
- @Component
- @Order(1) //顺序排第1,最先校验
- public class CheckParamFilterObject extends AbstractHandler {
-
- @Override
- public void doFilter(Request request, Response response) {
- System.out.println("非空参数检查");
- }
- }
-
- /**
- * 安全校验对象
- */
- @Component
- @Order(2) //校验顺序排第2
- public class CheckSecurityFilterObject extends AbstractHandler {
-
- @Override
- public void doFilter(Request request, Response response) {
- //invoke Security check
- System.out.println("安全调用校验");
- }
- }
- /**
- * 黑名单校验对象
- */
- @Component
- @Order(3) //校验顺序排第3
- public class CheckBlackFilterObject extends AbstractHandler {
-
- @Override
- public void doFilter(Request request, Response response) {
- //invoke black list check
- System.out.println("校验黑名单");
- }
- }
-
- /**
- * 规则拦截对象
- */
- @Component
- @Order(4) //校验顺序排第4
- public class CheckRuleFilterObject extends AbstractHandler {
-
- @Override
- public void doFilter(Request request, Response response) {
- //check rule
- System.out.println("check rule");
- }
- }
3.对象链连起来(初始化)&& 使用
- @Component("ChainPatternDemo")
- public class ChainPatternDemo {
-
- //自动注入各个责任链的对象
- @Autowired
- private List<AbstractHandler> abstractHandleList;
-
- private AbstractHandler abstractHandler;
-
- //spring注入后自动执行,责任链的对象连接起来
- @PostConstruct
- public void initializeChainFilter(){
- for(int i = 0;i<abstractHandleList.size();i++){
- if(i == 0){
- abstractHandler = abstractHandleList.get(0);
- }else{
- AbstractHandler currentHander = abstractHandleList.get(i - 1);
- AbstractHandler nextHander = abstractHandleList.get(i);
- currentHander.setNextHandler(nextHander);
- }
- }
- }
-
- //直接调用这个方法使用
- public Response exec(Request request, Response response) {
- abstractHandler.filter(request, response);
- return response;
- }
-
- public AbstractHandler getAbstractHandler() {
- return abstractHandler;
- }
-
- public void setAbstractHandler(AbstractHandler abstractHandler) {
- this.abstractHandler = abstractHandler;
- }
- }
4.运行结果如下:
