iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java设计模式之责任链模式
  • 407
分享到

Java设计模式之责任链模式

2024-04-02 19:04:59 407人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

本文通过图书馆管理系统中,用户名校验、密码校验、需要增加问题,每次都要增加if判断语句,将其改用责任链模式进行链式调用,为了让代码更加的优雅,我们使用之前学过的建造者模式就代码进行改

本文通过图书馆管理系统中,用户名校验、密码校验、需要增加问题,每次都要增加if判断语句,将其改用责任链模式进行链式调用,为了让代码更加的优雅,我们使用之前学过的建造者模式就代码进行改造。接着我们会介绍责任链模式在我们常用的框架中的运用,最后是责任链模式的优缺点和应用场景。

读者可以拉取完整代码到本地进行学习,实现代码均测试通过后上传到码云,本地源码下载。

一、引出问题

小王给老王打造了一套图书馆管理系统,随着访问量的不断增加,老王要求增加访问的用户名校验。

小王说这有何难,说着就在用户访问图书馆之前加了一层判断语句,判断用户名是否合法。过了一段时间后,又给每个用户颁发了一个密码,就需要在用户名校验通过以后校验密码。

小王就准备在用户名的判断语句后,增加密码的校验语句。老王赶忙拦住了要继续更改代码的小王。如果以后再增加角色校验、权限校验、你准备写多少个判断语句。

而且你把软件设计原则中的——开闭原则丢到哪里去了。

你可以考虑使用一种模式,将所有的校验方法都独立出来一个类,每一个类只负责处理各自的校验逻辑,当前的校验类通过以后传递给下一个校验类进行处理,这样每次增加新的逻辑判断都只需要增加校验类就行了。

就像是一条流水线,每个类负责处理线上的一个环节。

二、责任链模式的概念和使用

实际上,老王提出来的正是行为型设计模式中的——**责任链模式。

责任链模式正如它的名字一样,将每个职责的步骤串联起来执行,并且一个步骤执行完成之后才能够执行下一个步骤。

从名字可以看出通常责任链模式使用链表来完成。 因此当执行任务的请求发起时,从责任链上第一步开始往下传递,直到最后一个步骤完成。

在责任链模式当中, 客户端只用执行一次流程开始的请求便不再需要参与到流程执行当中,责任链上的流程便能够自己一直往下执行,

客户端同样也并不关心执行流程细节,从而实现与流程之间的解耦。

责任链模式需要有两个角色:

抽象处理器(Handler):处理器抽象接口,定义了处理请求的方法和执行下一步处理的处理器。

具体处理器(ConcreteHandler):执行请求的具体实现,先根据请求执行处理逻辑,完成之后将请求交给下一个处理器执行。

基于责任链模式实现图书馆的用户名校验和密码校验。

抽象处理器:


public abstract class Handler {

    private Handler next;

    public Handler getNext() {
        return next;
    }

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

    public abstract void handle(Object request);


}

用户名校验处理器:


public class ConcreteHandlerUsername extends Handler{
    @Override
    public void handle(Object request) {

        //相应的业务逻辑...
        System.out.println("用户名校验通过. 参数: " + request);

        //调用链路中下一个节点的处理方法
        if (getNext() != null) {

            getNext().handle(request);
        }

    }
}

密码校验器:


public class ConcreteHandlerPassWord extends Handler{
    @Override
    public void handle(Object request) {

        //相应的业务逻辑...

        System.out.println("密码校验通过. 参数: " + request);

        //调用链路中下一个节点的处理方法
        if (getNext() != null){

            getNext().handle(request);
        }

    }
}

客户端调用:

public class Client {

    //普通模式----------
    public static void main(String[] args) {
        Handler concreteHandler1 = new ConcreteHandlerUsername();
        Handler concreteHandler2 = new ConcreteHandlerPassword();
    
       concreteHandler1.setNext(concreteHandler2);
    
       concreteHandler1.handle("用户名tcy");
    
    }
}

  用户名校验通过. 参数: 用户名tcy
  密码校验通过. 参数: 用户名tcy

这样我们就实现了责任链模式,但是这种方式我们注意到,调用方调用的时候手动将两个处理器set到一起,如果这条链路很长的时候,这样的代码实在是太不优雅了。

将我们曾经学过的设计模式扒出来,看使用哪种模式能让它看起来更优雅一点。

三、责任链模式+建造者模式

我们看建造型设计模式的文章,看建造者模式中的典型应用中的Lombok。

参考Lombok的 @Builder例子,是不是和我们这个有着些许相似呢?

我们在Handle的类中创建一个Builder内部类。


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

    public Builder addHanlder(Handler handler){
        //head==null表示第一次添加到队列
        if (null == head){
            head = this.tail = handler;
            return this;
        }
        //原tail节点指向新添加进来的节点
        this.tail.setNext(handler);
        //新添加进来的节点设置为tail节点
        this.tail = handler;
        return this;
    }

    public Handler build(){
        return this.head;
    }
}

该内部类更像是一个链表结构,定义一个头和尾对象,add方法是向链接的头尾中赋值,build返回头元素方便开始链式调用。我们对调用方代码进行改造。

//建造者模式---------
public static void main(String[] args) {
    Handler.Builder builder = new Handler.Builder();
    builder.addHanlder(new ConcreteHandlerUsername())
            .addHanlder(new ConcreteHandlerPassword());
    builder.build().handle("用户名tcy");

}

这样的实现方式比原方式优雅多了。责任链模式本身是很简单的,如果将责任链模式和建造者模式组合起来使用就没那么容易理解了。

在实际使用中往往不是一个单一的设计模式,更多的是多种组合模式组成的“四不像”,实际上这并不是一件轻松的事。

四、责任链模式在源码运用

为了加深理解我们继续深入责任链模式在spring中的运用。

Spring WEB 中的 HandlerInterceptor,里面有preHandle()postHandle()afterCompletion()三个方法,实现这三个方法可以分别在调用"Controller"方法之前,调用"Controller"方法之后渲染"ModelAndView"之前,以及渲染"ModelAndView"之后执行。

public interface HandlerInterceptor {
    default boolean preHandle(httpservletRequest request, HttpServletResponse response, Object handler)
            throws Exception {

        return true;
    }

    default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            @Nullable ModelAndView modelAndView) throws Exception {
    }

    default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
            @Nullable Exception ex) throws Exception {
    }

}

HandlerInterceptor就是角色中的抽象处理者,HandlerExecutionChain相当于上述中的Client,用于调用责任链上的各个环节。

public class HandlerExecutionChain {
...

@Nullable
private HandlerInterceptor[] interceptors;

private int interceptorIndex = -1;

boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
    HandlerInterceptor[] interceptors = getInterceptors();
    if (!ObjectUtils.isEmpty(interceptors)) {
        for (int i = 0; i < interceptors.length; i++) {
            HandlerInterceptor interceptor = interceptors[i];
            if (!interceptor.preHandle(request, response, this.handler)) {
                triggerAfterCompletion(request, response, null);
                return false;
            }
            this.interceptorIndex = i;
        }
    }
    return true;
}

void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv)
        throws Exception {

    HandlerInterceptor[] interceptors = getInterceptors();
    if (!ObjectUtils.isEmpty(interceptors)) {
        for (int i = interceptors.length - 1; i >= 0; i--) {
            HandlerInterceptor interceptor = interceptors[i];
            interceptor.postHandle(request, response, this.handler, mv);
        }
    }
}

void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex)
        throws Exception {

    HandlerInterceptor[] interceptors = getInterceptors();
    if (!ObjectUtils.isEmpty(interceptors)) {
        for (int i = this.interceptorIndex; i >= 0; i--) {
            HandlerInterceptor interceptor = interceptors[i];
            try {
                interceptor.afterCompletion(request, response, this.handler, ex);
            }
            catch (Throwable ex2) {
                logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);
            }
        }
    }
}
}

私有的数组 private HandlerInterceptor[] interceptors 用于存储责任链的每个环节,,然后通过interceptorIndex作为指针去遍历责任链数组按顺序调用处理者。

结合我们上面给出的例子,在Spring中的应用是比较容易理解的。

在Servlet的一系列拦截器也是采用的责任链模式,有兴趣的读者可以深入研究一下。

五、总结

当必须按顺序执行多个处理者时,可以考虑使用责任链模式。如果处理者的顺序及其必须在运行时改变时,可以考虑使用责任链模式。责任链的模式是缺点也很明显,增加了系统的复杂性。

但是要切忌避免过度设计,在实际应用中,校验用户名和密码的业务逻辑并没有那么的复杂,可能只是一个判断语句,使用设计模式只会增加系统的复杂性,而在shiro、SpringSecurity、springMVC的拦截器中使用责任链模式是一个好的选择。

如果在你的项目业务中需要定义一系列拦截器,那么使用责任链模式就是一个比较不错的选择。

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对编程网的支持。如果你想了解更多相关内容请查看下面相关链接

--结束END--

本文标题: Java设计模式之责任链模式

本文链接: https://www.lsjlt.com/news/168829.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java设计模式之责任链模式
    本文通过图书馆管理系统中,用户名校验、密码校验、需要增加问题,每次都要增加if判断语句,将其改用责任链模式进行链式调用,为了让代码更加的优雅,我们使用之前学过的建造者模式就代码进行改...
    99+
    2024-04-02
  • Java实现设计模式之责任链模式
    目录1.什么是责任链模式2.如何实现3.代码实现4.总结1.什么是责任链模式 当一个请求可能需要多个对象中的某个进行处理时,将这些对象连成一条链,并沿者这条链传递该请求,知道有一个对...
    99+
    2024-04-02
  • Java设计模式之责任链模式详解
    一、前言 各个部门协同合作完成一个任务,每个部门都有各自的职责,一个部门完成后,变回转交给下一个部门,直到所有部门都处理了,这个任务才完成。 将请求与处理解耦。 处理者只需要关注自己...
    99+
    2024-04-02
  • Java 设计模式之责任链模式及异步责任链详解
    目录一、定义二、普通责任链模式三、异步责任链模式一、定义 责任链模式(Chain of Responsibility Pattern):避免将一个请求的发送者与接受者耦合在一起,让多...
    99+
    2024-04-02
  • Java设计模式之java责任链模式详解
    目录概述结构总结在本讲,我们来学习一下行为型模式里面的第四个设计模式,即责任链模式。 概述 在学习责任链模式之前,我们先来看一下下面这段描述。 在现实生活中,常常会出现这样的事例:一...
    99+
    2024-04-02
  • java设计模式(实战)-责任链模式
    目录一:模式说明二:项目实战三:源代码一:模式说明 模式定义:使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,...
    99+
    2024-04-02
  • 详解Java实现设计模式之责任链模式
    目录一、模拟业务需求二、小步小跑的迭代开发三、系统对数据的校验要求四、新建一个抽象类五、子类的实现六、构建责任链和调用七、可维护性八、总结8.1、责任链模式8.2、责任链模式适用的场...
    99+
    2024-04-02
  • Java设计模式之责任链模式的示例详解
    目录应用场景实际代码案例无模式情况下的代码采用责任链模式优化代码采用建造者+责任链模式优化代码责任链模式优缺点责任链模式是将链中的每一个节点看做是一个对象,每个节点处理的请求均不相同...
    99+
    2022-11-13
    Java 设计模式 责任链模式 Java 责任链模式
  • 每天一个设计模式之责任链模式
    作者按:《每天一个设计模式》旨在初步领会设计模式的精髓,目前采用javascript和python两种语言实现。诚然,每种设计模式都有多种实现方式,但此小册只记录最直截了当的实现方式 :) 0. 项目地址 责任链模式·代码 《每天一个设...
    99+
    2023-01-31
    模式 责任
  • Java中常用的设计模式之责任链模式详解
    目录优点缺点使用场景一、实现方式1、处理抽象类2、学生处理类3、老师处理类4、校长处理类5、测试二、实现方式1、订单信息类2、订单校验接口3、库存校验器4、价格校验器5、测试总结优点...
    99+
    2024-04-02
  • Java通俗易懂系列设计模式之责任链模式
    目录概述JDK中的责任链模式示例责任链设计模式示例责任链设计模式 - 基类和接口责任链模式 - 链实现责任链设计模式 - 创建链责任链设计模式类图责任链设计模式重点JDK中的责任链模...
    99+
    2024-04-02
  • Java设计模式之职责链模式详解
    目录前言一、职责链模式的定义与特点二、职责链模式的结构三、职责链模式案例前言 本文简单介绍了设计模式的一种——职责链模式  一、职责链模式的定义与特点 定义: 为了避免请求发送者与多...
    99+
    2024-04-02
  • JavaScript设计模式之职责链模式
    目录概述代码实现参数定义实现职责链模式实现改良概述 职责链模式是设计模式中行为型的一种设计模式; 定义:使多个对象都有机会处理请求,从而避免请求的发送者与接收者之间的耦合关系,将这些...
    99+
    2024-04-02
  • Python设计模式行为型责任链模式
    目录一、责任链模式二、应用场景三、代码示例一、责任链模式 责任链模式,将多个处理方法连接成一条链条,请求将在这条链条上流动直到该链条中有一个节点可以处理该请求。通常这条链条是一个对象...
    99+
    2024-04-02
  • java设计模式中的责任链模式是什么
    本篇文章为大家展示了java设计模式中的责任链模式是什么,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。一:模式说明模式定义:使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。...
    99+
    2023-06-22
  • 设计模式之如何掌握责任链
    本篇内容主要讲解“设计模式之如何掌握责任链”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“设计模式之如何掌握责任链”吧!例子假设你也"穿越"到...
    99+
    2024-04-02
  • C#设计模式实现之生成器模式和责任链模式
    目录生成器设计类图: 实现代码:优点:用途与缺点:责任链设计类图:实现代码:优点:用途和缺点:总结生成器 生成器模式:封装一个产品的构造过程,并允许按步骤构造。 现又一个...
    99+
    2024-04-02
  • 深入了解Java设计模式之职责链模式
    目录定义解决的问题核心要点类图代码实现抽象父类执行者-三个客户端拓展应用场景定义 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系,将这个对象连成一条链,并沿着...
    99+
    2024-04-02
  • java设计模式责任链模式原理案例详解
    目录引言责任链模式定义类图角色核心示例代码1、对请求处理者的抽象2、对请求处理者的抽象3、责任链的创建责任链实现请假案例案例类图可扩展性纯与不纯的责任链模式纯的责任链模式不纯的责任链...
    99+
    2024-04-02
  • 深入理解Java设计模式之职责链模式
    目录一、什么是职责链模式二、职责链模式的结构四、职责链模式的使用场景五、职责链模式的实现一、什么是职责链模式二、职责链模式的结构四、职责链模式的使用场景五、职责链模式的实现六、总结六...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作