• 23种设计模式(13)


    1、定义

    使多个对象都有机会处理请求,从而避免请求的发送者和接受者质检的耦合关系。将这个接收对象连成一条链,并沿着这条链传递请求,直到有一个对象处理他为止。

    2、UML 图

    8fHV6x.png

    3、组成

    • 抽象处理器(Handler):主要包含了处理方法handlerRequest和转交对象nextHandler,他的思想是,如果自己能处理则自己处理,否则交给转交对象处理
    • 处理器实现类(FirstHandler):处理器的实现类,每个实现类自己定义处理逻辑

    4、代码

    先来看一个反面例子代码,使用大量的if判断来选择执行逻辑:

    public Response handleRequest(Request request) {
        Level level = request.getLevel();
        if (1 == level) {
        	Handler1.handleRequest(request);
        } else if (2 == level) {
        	Handler2.handleRequest(request);
        } else if (3 == level) {
        	Handler3.handleRequest(request);
    		}
        throw new RuntimeException("无法处理 ......")
    }
    

    这样的代码有以下缺点:

    • 代码臃肿:如果判断条件不是简单的 1==level,而是更复杂的计算,那代码可读性会很不好;
    • 耦合性高:如果新加一种情况,需要新加 if else语句,改变了原来代码,违反了 封闭-开放 原则。

    以下是使用责任链模式的代码:

    // 抽象处理类
    public abstract class Handler {
    		// 下一个处理器处理
        protected Handler nextHandler;
    
        void setNextHandler(Handler nextHandler){
            this.nextHandler = nextHandler;
        }
    
        final Response handleRequest(Request request){
          	// 如果自己能处理,则自己处理
            if(request.getLevel() == getHandlerLevel()){
                return this.doHandler(request);
            }
            System.out.println("本处理器:"+getHandlerLevel()+" 无法处理,开始转交 ......");
            if(null != this.nextHandler){
              // 如果不能处理,转交给下一个处理器处理
                return this.nextHandler.handleRequest(request);
            } else {
                System.out.println("无合适的处理器,处理失败 ......");
            }
            return null;
        }
    		// 自己处理的任务标识
        abstract Level getHandlerLevel();
    		// 实际处理逻辑,子类自己定义
        abstract Response doHandler(Request request);
    }
    
    // 任务标识,用于区分用哪个处理器处理
    public enum Level {
        FIRST_LEVEL,
        SECOND_LEVEL,
        THIRD_LEVEL;
    }
    
    //请求类
    public class Request {
        private Level level;
      
        public Request(Level level){
            this.level = level;
        }
      
        public Level getLevel() {
            return level;
        }
    }
    
    // 处理结果类
    public class Response {
    }
    
    // 第一个处理器
    public class FirstConcreteHandler extends Handler {
        @Override
        Level getHandlerLevel() {
            return Level.FIRST_LEVEL;
        }
    
        @Override
        Response doHandler(Request request) {
            System.out.println("本处理器:"+getHandlerLevel()+" 开始处理 .....");
            return null;
        }
    }
    
    // 第二个处理器
    public class SecondConcreteHandler extends Handler {
        @Override
        Level getHandlerLevel() {
            return Level.SECOND_LEVEL;
        }
    
        @Override
        Response doHandler(Request request) {
            System.out.println("本处理器:"+getHandlerLevel()+" 开始处理 .....");
            return null;
        }
    }
    
    // 第三个处理器
    public class ThirdConcreteHandler extends Handler {
        @Override
        Level getHandlerLevel() {
            return Level.THIRD_LEVEL;
        }
    
        @Override
        Response doHandler(Request request) {
            System.out.println("本处理器:"+getHandlerLevel()+" 开始处理 .....");
            return null;
        }
    }
    
    //调用者
    public class Main {
    
        public static void main(String[] args) {
            Handler firstHandler = new FirstConcreteHandler();
            Handler secondHandler = new SecondConcreteHandler();
            Handler thirdHandler = new ThirdConcreteHandler();
    
            firstHandler.setNextHandler(secondHandler);
            secondHandler.setNextHandler(thirdHandler);
    				// 需要第三个处理类处理
            Request request = new Request(Level.THIRD_LEVEL);
            firstHandler.handleRequest(request);
        }
    }
    
    

    输出结果如下:

    本处理器:FIRST_LEVEL 无法处理,开始转交 ......
    本处理器:SECOND_LEVEL 无法处理,开始转交 ......
    本处理器:THIRD_LEVEL 开始处理 .....
    

    5、优缺点

    • 只需要在代码中将各中情况链式创起来,使用者只需要知道一个入口,而不用管具体的执行逻辑;
    • 责任链模式是变相版的if else语句,如果链过长,会过量消耗性能;
    • 责任链的链不能出现循引用的情况,否则会出现死循环

    6、适用场景

    责任链模式其实就是一个灵活版的if…else…语句,只不过它把判断条件放在每个链的节点类中。如觉得代码中if…else…语句使得程序可读性不好,可以考虑责任链模式。

  • 相关阅读:
    pip备忘录
    Vue.js---------------1引入
    centos安装数据库
    Python之网络编程二
    Python之协议
    Python高级
    jvm-3学习教程
    jvm学习-2
    jvm相关学习
    八种常用的排序算法
  • 原文地址:https://www.cnblogs.com/moongeek/p/12556425.html
Copyright © 2020-2023  润新知