Java设计模式之责任链模式的示例详解

目录
  • 应用场景
  • 实际代码案例
    • 无模式情况下的代码
    • 采用责任链模式优化代码
    • 采用建造者+责任链模式优化代码
  • 责任链模式优缺点

责任链模式是将链中的每一个节点看做是一个对象,每个节点处理的请求均不相同,且内部自动维护下一个节点对象,当一个请求从链式的首段发出时,会沿着链的路径依次传递给每一个节点对象,直至有对象处理这个请求位置,属于行为模式。

这里需要注意的是每个节点都能对对象进行一定的处理(也可以不处理),处理完成之后节点再进行判断还要进行后续处理还是说传递给下一个节点。

应用场景

首先举一个日常的例子,比如我们申请开发票,首先我们要写好报销单,首先要你的部门领导审批,部门领导审批不通过直接打回,审批通过再由公司的总经理审批这里审批通过才算成审批完成。这种情况就很适合使用责任链模式。

总结一下责任链主要适用一下几种情况:

  • 多个对象可以处理同一个请求,但是具体由那个对象处理完成则在运行时决定。
  • 不明确指定接收者的情况下,向多个对象中的一个提交一个请求

可以看一下责任链模式的通用UML类图:

通过类图可以看到总共包含以下角色:

  • 抽象处理者:主要是定义处理请求的方法以及维护下一个处理结点的对象的引用
  • 具体处理者:处理的具体实现

责任链的精髓在于将很多处理节点行成个链式结构,并允许结点自身决定是否进行处理或者转发。

实际代码案例

下面举一个我们在开发时经常会遇到的一种情况:登录 比如我们开发一个管理系统在登录的时候往往我们会先判断客户端传递的账号及密码是否为空但凡有一个是空肯定是不能继续往下走的,然后就是根据用户账号密码拿到用户的所有信息,如果能拿到继续周下一步,拿不到则是报错提示用户不存在,到下一步又会判断当前用户的权限。

无模式情况下的代码

private String login(String username,String password) {
    if(username == null || password == null) {
        return "账户或者密码为null";
    }
    User user = queryUserInfo(username, password);
    if(user == null) {
        return "找不到用户";
    }
    if(!Objects.equals(user.getRoleName(), "超管")){
        return "没有权限";
    }
    return "登录成功";

}

private User queryUserInfo(String username,String password){
    if(Objects.equals(username, "土豆") && Objects.equals(password, "666666")) {
        return new User(username,password,"超管");
    }else if(Objects.equals(username, "土豆2号") && Objects.equals(password, "666666")){
        return new User(username,password,"普通员工");
    }
    return null;
}

发现判断代码都冗余在一个方法里面,后续改动修改都需要修改中这个方法不满足开闭原则。

采用责任链模式优化代码

首先创建抽象类规定抽象方法以及维护下一个节点

public abstract class Handler {
    protected Handler next;

    public void setNext(Handler next) {
        this.next = next;
    }

    public abstract void doHandler(User user);
}

然后就是创建多个实现逻辑的节点对象:

public class ValidatedHandler extends Handler {
    @Override
    public void doHandler(User user) {
        if(user.getUsername() == null || user.getPassword() == null) {
            System.out.println("账户或者密码为null");
        }else{
            this.next.doHandler(user);
        }
    }
}
public class UserHandler extends Handler{
    @Override
    public void doHandler(User user) {
        queryUserInfo(user);
        if(user.getRoleName() == null){
            System.out.println("没有找到用户");
        }else{
            this.next.doHandler(user);
        }
    }
    private static void queryUserInfo(User user){
        if(Objects.equals(user.getUsername(), "土豆") && Objects.equals(user.getPassword(), "666666")) {
            user.setRoleName("超管");
        }else if(Objects.equals(user.getUsername(), "土豆2号") && Objects.equals(user.getPassword(), "666666")){
            user.setRoleName("普通员工");
        }
    }
}
public class AuthHandler extends Handler{
    @Override
    public void doHandler(User user) {
        if(!Objects.equals(user.getRoleName(), "超管")){
            System.out.println("没有权限");
        }
        System.out.println("登入成功");
    }
}

最后调用:

public static void main(String[] args) {
    User user = new User("土豆","666666");
    Handler validatedHandler = new ValidatedHandler();
    Handler userHandler = new UserHandler();
    Handler authHandler = new AuthHandler();
    validatedHandler.setNext(userHandler);
    userHandler.setNext(authHandler);
    validatedHandler.doHandler(user);

}

可以看一下UML类图:

采用建造者+责任链模式优化代码

上述的代码发现维护链表的操作在用户调用的那一层,链表的组装过于复杂,这个时候我们可以使用建造者模式, 自动维护链表的组装,调用者只需要指定链表的顺序即可 主要修改Handler内代码:

public abstract class Handler {
    protected Handler next;

    public void setNext(Handler next) {
        this.next = next;
    }

    public abstract void doHandler(User user);

    public static class Builder {
        private Handler head;
        private Handler tail;

        public Builder addHandler(Handler handler) {
            if(this.head == null){
                this.head = this.tail = handler;
                return this;
            }
            this.tail.setNext(handler);
            this.tail = handler;
            return this;
        }

        public Handler build() {
            return this.head;
        }
    }
}
Handler.Builder builder = new Handler.Builder();
builder.addHandler(new ValidatedHandler())
        .addHandler(new UserHandler())
        .addHandler(new AuthHandler());
builder.build().doHandler(user);

可发现调用者只需要关心链表顺序写入就好

责任链模式优缺点

优点:

  • 请求与处理解耦
  • 处理者只需要关心自己的处理逻辑即可,如果不是自己的直接转发
  • 具有链式传递功能,请求者不需要关系链路结构等待结果就好
  • 易于维护,可以很灵活的修改链路的结构新增或者删除,符合开闭原则

缺点:

  • 会出现循环引用的情况
  • 责任链太长会影响性能

到此这篇关于Java设计模式之责任链模式的示例详解的文章就介绍到这了,更多相关Java责任链模式内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java 设计模式之责任链模式及异步责任链详解

    目录 一.定义 二.普通责任链模式 三.异步责任链模式 一.定义 责任链模式(Chain of Responsibility Pattern):避免将一个请求的发送者与接受者耦合在一起,让多个对象都有机会处理请求.将接受请求的对象连接成一条链,并且沿着这条链传递请求,直到有一个对象能够处理它为止. 在很多源码都有涉及,如Mybatis拦截器.Filter- 责任链模式属于行为型模式. 二.普通责任链模式 抽象处理类:AbstractProcessor /** * 抽象处理类 */ public

  • Java实现设计模式之责任链模式

    目录 1.什么是责任链模式 2.如何实现 3.代码实现 4.总结 1.什么是责任链模式 当一个请求可能需要多个对象中的某个进行处理时,将这些对象连成一条链,并沿者这条链传递该请求,知道有一个对象处理它为止.这样的情况或需求时,可以采用责任链模式. 2.如何实现 1)处理者接口(Handler),负责定义处理请求的抽象方法,并设置下一个处理着的方法. 2)具体处理者,实现Handler接口中定义的方法.实现处理用户请求的逻辑,并设置下一个处理请求的对象.如果能够处理用户求情就处理,如果不能处理,交

  • Java设计模式之java责任链模式详解

    目录 概述 结构 总结 在本讲,我们来学习一下行为型模式里面的第四个设计模式,即责任链模式. 概述 在学习责任链模式之前,我们先来看一下下面这段描述. 在现实生活中,常常会出现这样的事例:一个请求有多个对象可以处理,但每个对象的处理条件或权限不同.例如,公司员工请假,可批假的领导有部门负责人.副总经理.总经理等,但是每个领导能批准的天数不同,员工必须根据自己要请假的天数去找不同的领导签名,也就是说员工必须记住每个领导的姓名.电话和地址等信息,这增加了员工请假的难度.因为领导有很多,员工到底找哪位

  • java设计模式(实战)-责任链模式

    目录 一:模式说明 二:项目实战 三:源代码 一:模式说明 模式定义:使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止. 责任链模式的重点是在“链”上,由一条链去处理相似的请求在链中决定谁来处理这个请求,并返回相应的结果(取自<设计模式之禅>). 翻译:Client对象调用一个处理者(类)的方法,可能有多个处理者(实现类),但是该对象只需要调用第一个处理者(类)即可,该模式会自动分配谁来处理这个请求:这

  • 详解Java实现设计模式之责任链模式

    一.模拟业务需求 假设我们现在需要在我们的系统中导入一批关于学生信息的Excel的数据,其主要的信息有:学号.姓名.年龄.性别等等,在导入系统的时候,我们肯定不能直接的保存到数据库,我们肯定是先要对这个Excel的数据进行校验,看是否符合系统的要求,只有都符合了系统的要求了,我们把这些数据保存到数据库中去.假如我们的学生对应的实体类如下: @Data public class Student { /** * 学生编号 */ private String stNo; /** * 学生姓名 */ p

  • Java中常用的设计模式之责任链模式详解

    目录 优点 缺点 使用场景 一.实现方式 1.处理抽象类 2.学生处理类 3.老师处理类 4.校长处理类 5.测试 二.实现方式 1.订单信息类 2.订单校验接口 3.库存校验器 4.价格校验器 5.测试 总结 优点 1.降低耦合度.它将请求的发送者和接收者解耦. 2.简化了对象.使得对象不需要知道链的结构. 3.增强给对象指派职责的灵活性.通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任. 4.增加新的请求处理类很方便. 缺点 1.不能保证请求一定被接收. 2.系统性能将受到一

  • Java设计模式中责任链模式详解

    目录 1.责任链设计模式的定义 2.责任链设计模式的优点与不足 3.责任链设计模式的实现思路 4.责任链设计模式应用实例 5.责任链设计模式应用场景 编程是一门艺术,大批量的改动显然是非常丑陋的做法,用心的琢磨写的代码让它变的更美观. 在现实生活中,一个事件需要经过多个对象处理是很常见的场景.例如,采购审批流程.请假流程等.公司员工请假,可批假的领导有部门负责人.副总经理.总经理等,但每个领导能批准的天数不同,员工必须根据需要请假的天数去找不同的领导签名,也就是说员工必须记住每个领导的姓名.电话

  • Java设计模式之责任链模式的示例详解

    目录 应用场景 实际代码案例 无模式情况下的代码 采用责任链模式优化代码 采用建造者+责任链模式优化代码 责任链模式优缺点 责任链模式是将链中的每一个节点看做是一个对象,每个节点处理的请求均不相同,且内部自动维护下一个节点对象,当一个请求从链式的首段发出时,会沿着链的路径依次传递给每一个节点对象,直至有对象处理这个请求位置,属于行为模式. 这里需要注意的是每个节点都能对对象进行一定的处理(也可以不处理),处理完成之后节点再进行判断还要进行后续处理还是说传递给下一个节点. 应用场景 首先举一个日常

  • java设计模式责任链模式原理案例详解

    目录 引言 责任链模式定义 类图 角色 核心 示例代码 1.对请求处理者的抽象 2.对请求处理者的抽象 3.责任链的创建 责任链实现请假案例 案例类图 可扩展性 纯与不纯的责任链模式 纯的责任链模式 不纯的责任链模式 责任链模式主要优点 职责链模式的主要缺点 适用场景 模拟实现Tomcat中的过滤器机制 运行过程如下 分析Tomcat 过滤器中的责任链模式 引言 以请假流程为例,一般公司普通员工的请假流程简化如下: 普通员工发起一个请假申请,当请假天数小于3天时只需要得到主管批准即可:当请假天数

  • 一文搞懂Java设计模式之责任链模式

    简述: 前端时间再看一些类库的源码,发现责任链模式的强大之处,尤其是和建造者模式的结合后强大的动态可扩展性更是牛逼的一塌糊涂.接下来赶紧了解一下吧! 我们先来了解一下什么是责任链模式: 职责链模式(Chain of Responsibility):使多个对象都有机会处理同一个请求,从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. 应用场景: 为完成同一个请求,如果存在多个请求处理器以及未知请求处理器个数或者请求处理器可动态配置的

  • Java设计模式之责任链模式的概念、实现以及netty中的责任链模式

    本文先介绍了责任链模式的概念及简单实现.再贴了netty中对责任链的实现.最后总结了一点点思考. 1.概念相关 1.1.概念 责任链模式为请求创建了一个接收者对象的链,每个接收者都包含对另一个接收者的引用.如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,沿着这条链传递请求,直到有对象处理它为止. 1.2.解决了什么: 客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了. 1.3.场景: 1.有多个对象可以处理同一

  • Java设计模式之责任链模式

    设计者往往会用拦截器去代替动态代理,然后将拦截器的接口提供给开发者,从而简化开发者的开发难度,但是拦截器可能有多个.举个例子,一个程序员需要请假一周,如果把请假申请单看成一个对象,那么它需要经过项目经理.部门经理.人事等多个角色的审批,每个角色都有机会通过拦截这个申请单进行审批或者修改.这事就要考虑提供项目经理.部门经理和人事的处理逻辑,所以需要提供3个拦截器,二传递的则是请假申请单. 当一个对象在一条链上被多个拦截器处理(拦截器也可以选择不拦截处理它)时,我们把这样的设计模式成为责任链模式,它

  • JAVA设计模式之责任链模式详解

    在阎宏博士的<JAVA与模式>一书中开头是这样描述责任链(Chain of Responsibility)模式的: 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任. 从击鼓传花谈起 击鼓传花是一种热闹而又紧张的饮酒游戏.在酒宴上宾客依次坐定位置,由一人击鼓,击鼓

  • Java设计模式之责任链模式(Chain of Responsibility模式)介绍

    Chain of Responsibility定义:Chain of Responsibility(CoR) 是用一系列类(classes)试图处理一个请求request,这些类之间是一个松散的耦合,唯一共同点是在他们之间传递request.也就是说,来了一个请求,A类先处理,如果没有处理,就传递到B类处理,如果没有处理,就传递到C类处理,就这样象一个链条(chain)一样传递下去. 如何使用责任链模式 虽然这一段是如何使用CoR,但是也是演示什么是CoR. 有一个Handler接口: 复制代码

随机推荐