Java设计模式——责任链模式

news/2024/5/19 15:05:44 标签: java, 设计模式, 责任链模式, 游戏SDK, 面试

简述

责任链模式是一种处理请求设计模式,属于行为设计模式。它允许多个处理器都有机会处理请求,直到某个请求被处理为止。责任链模式把多个处理器串成链,让请求在链上传递。

优缺点

优点

  1. 使得请求的发送者和处理者解藕。
  2. 添加新的处理者或者重新排列处理者的时候很容易。
  3. 可以控制处理者的顺序。

缺点

  1. 部分请求可能会没有被处理。

责任链模式的结构

  1. 处理者的基类:可以将所有处理者共用操作在这里处理。可以定义为不可修改,保存对下个处理者的成员变量。
  2. 具体处理者的实现类:每个处理者有自己的处理逻辑。也可以不处理本次请求,交给下一个处理者处理。
  3. 请求类:需要发送的请求类,一般结合建造者设计模式使用。
  4. 链条:将所有的处理者串成一个链条,让每个处理者都有机会处理请求。

应用场景

  1. 当程序需要使用不同方式处理不同种类的请求,请求类型和顺序预先未知。例如报销审批模式,当0-100额度,自动发送给 A 审批,100-200自动发送给 B 审批等等(这里可以通过A 也可以不通过A)
  2. 当请求必须按顺序执行时。比如请假审批模式,请假必须先经过直属lead审批,再经过部门经理审批,最后发送HR审批。
  3. 每个处理者分别处理给自请求,互不影响。比如订购系统,记录日志、检查权限、准备相关资源…这种一般是拦截器、过滤器,例如 OKHttp 源码里使用到的拦截器。

代码实现

  1. 基础处理类:放置处理者公共逻辑,比如声明下一个处理者的成员变量。

    java">public abstract class BaseHandler implements IHandler {
        protected BaseHandler mNextHandler;
    
        @Override
        public void nextHandler(BaseHandler handler) {
            this.mNextHandler = handler;
        }
    
    }
    
  2. 处理者的接口:定义需要实现的方法

    java">public interface IHandler {
    
        void nextHandler(BaseHandler handler);
    
        Result prosseed(Request params);
    }
    
  3. 具体的处理者:处理请求或者将请求发送给下一个处理者

    java">public  class Handler extends BaseHandler implements IHandler {
    
        @Override
        public void nextHandler(BaseHandler handler) {
            mNextHandler = handler;
        }
    
        @Override
        public Result prosseed(Request params) {
            // 这里处理逻辑,如果不处理,约定好返回 null 则交给下一个处理
            return null;
        }
    }
    
    // 第二个处理者
    public class BHandler extends BaseHandler implements IHandler {
    
        @Override
        public Result prosseed(Request params) {
            if (params.getName().equalsIgnoreCase("params")) {
                Result result = new Result();
                result.setResponse("result");
                return result;
            }
            return null;
        }
    }
    
  4. 将处理者串成链条:让每个处理者都有机会处理请求

    java">public class HandlerChain {
    
        private List<BaseHandler> handlers = new ArrayList<>();
    
        public void addHandler(BaseHandler handler) {
            handlers.add(handler);
        }
    
        public Result procees(Request request) throws IllegalAccessException {
            for (BaseHandler handler : handlers) {
                return handler.prosseed(request);
            }
            throw new IllegalAccessException("Can not handle request");
        }
    
    }
    
  5. 定义请求者和结果(一般结合建造者模式)

    java">class Request {
        // 可以对请求类进行扩展。一般结合建造者使用
        private String name;
    
        private String version;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getVersion() {
            return version;
        }
    
        public void setVersion(String version) {
            this.version = version;
        }
    }
    
    class Result {
        // 可以对结果类进行扩展
        private String response;
    
        public String getResponse() {
            return response;
        }
    
        public void setResponse(String response) {
            this.response = response;
        }
    }
    

http://www.niftyadmin.cn/n/63392.html

相关文章

react基础,操作属性样式事件。事件处理this指向问题,及案例

1.1 React 起源于 Facebook 于2013年5月开源. 是一个用于构建用户界面的 JavaScript 库, 与vue,angular并称前端三大框架&#xff0c;现在最新版本是18 特点&#xff1a;-数据驱动&#xff08;操作数据&#xff09; - 组件化 - 虚拟DOM 开发环境&#xff1a; cdn引入js <…

【csdn首发】全网爆火的从零到一落地接口自动化测试

前段时间写了一系列自动化测试相关的文章&#xff0c;当然更多的是方法和解决问题的思路角度去阐述我的一些观点。结合我自己实践自动化测试的一些经验以及个人理解&#xff0c;这篇文章来聊聊新手如何从零到一落地实践接口自动化测试。 为什么要做接口测试 测试理念的演变 早…

Linux管道字符转换命令:tr、col、join、paste、expand

tr tr命令可以用来删除一段信息当中的文字&#xff0c;或是进行文字信息的替换 tr 【-ds】SET1 ... 选项与参数&#xff1a; -d&#xff1a;删除信息中的SET1这个字符 -s&#xff1a;替换掉重复的字符 这个命令也可以写到正则表达式中&#xff0c;因为它是由正则表达式来替换…

Urho3D 事件Events

在脚本中&#xff0c;子系统通过以下全局财产可用&#xff1a;时间、文件系统、日志、缓存、网络、输入、ui、音频、引擎、图形、渲染器、脚本、控制台、debugHud、数据库。请注意&#xff0c;由于WorkQueue和Profiler的低级性质&#xff0c;它们不可用于脚本。 事件本身不需要…

python迭代器与iter()函数实例教程

本文介绍了python迭代器与iter()函数的用法&#xff0c;Python 的迭代无缝地支持序列对象&#xff0c;而且它还允许程序员迭代非序列类型&#xff0c;包括用户定义的对象。 迭代器是在版本 2.2 被加入 Python 的&#xff0c;它为类序列对象提供了一个类序列的接口。 序列是一组…

9. QML_OpenGL--2. 在QQuick中搭建加载OpenGL框架

1. 说明&#xff1a; OPenGL一般在 QtWidget 中使用&#xff0c;但目前使用 QML 做界面开发是一种趋势&#xff0c;同时在QML中使用OPenGL进行渲染也是十分必要&#xff0c;文章简单介绍如何在QML中使用 OPenGL&#xff0c;搭建了一种基本的框架。整体思路和在 QtWidget 中类似…

Hudi-基本概念(时间轴、文件布局、索引、表类型、查询类型、数据写、数据读、Compaction)

文章目录基本概念时间轴(TimeLine)文件布局&#xff08;File Layout&#xff09;Hudi表的文件结构Hudi存储的两个部分Hudi的具体文件说明索引&#xff08;Index&#xff09;原理索引选项全局索引与非全局索引索引的选择策略对事实表的延迟更新对事件表的去重对维度表的随机更删…

Java开发学习(五十)----MyBatisPlus快速开发之代码生成器解析

1、代码生成器原理分析 造句: 我们可以往空白内容进行填词造句&#xff0c;比如: 在比如: 观察我们之前写的代码&#xff0c;会发现其中也会有很多重复内容&#xff0c;比如: 那我们就想&#xff0c;如果我想做一个Book模块的开发&#xff0c;是不是只需要将红色部分的内容全部…