【设计模式】行为型模式-第 3 章第 1 讲【责任链模式】

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 【设计模式】行为型模式-第 3 章第 1 讲【责任链模式】

目录

1、责任链模式的概念

1.1、百度百科对责任链的定义

1.2、责任链模式

2、责任链模式的作用

3、实现

3.1、责任链模式的通用类图,如下图 1-1:

3.2、代码实现案例

4、责任链的优缺点

4.1、优点

4.2、缺点

5、责任链模式的应用场景

6、结语

前言

这一章节主要介绍行为型模式。

上一章节,我们介绍的是创建型模式,主要关注对象的创建,而这一章节的行为型模式主要关注对象交互、通信和控制流。

大多数行为型模式都基于组合和委托而不是继承。

接下来我们将在这一章节中讲解以下行为型模式:

责任链模式
命令模式
解释器模式
迭代器模式
观察者模式
中介者模式
备忘录模式
状态模式
策略模式
模板方法模式
空对象模式
访问者模式

1、责任链模式的概念

1.1、百度百科对责任链的定义

责任链模式是一种设计模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。

1.2、责任链模式

顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。

计算机软件是用来处理信息的,有多种不同的方式来组织和处理信息。之前我们提过设计模式需要遵循的原则,在面向对象编程中,我们应该赋予一个类单一职责,从而使得类容易维护和扩展。

设想一个场景,需要对一批从客户端来的数据进行多种不同的操作,我们会使用多个不同的类负责不同的操作,而不是使用一个类集成所有的操作,这样做能让代码松耦合且简洁。

这些类被称为处理器,第一个处理器会接收请求,如果它需要执行操作则会进行一次调用,如果不需要则会传递给第二个处理器。类似地,第二个处理器确认并将请求传递给责任链中下一个处理器。

2、责任链模式的作用

目的:避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,如果链上当前处理器可以处理,就处理,不能处理,就把请求传递给下一个处理器,就这样直到有对象处理它为止。

主要解决:职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了。

3、实现

3.1、责任链模式的通用类图,如下图 1-1:

4127e1c884974fafa0871a92a6d46ac4.png


图 1-1


图1-1中包含以下三个类:

Client(客户端):客户端是使用责任链模式的应用程序的主要结构。它的职责是实例化一个处理器的链,然后在第一个对象中调用 handleRequest 方法。

Handler(处理器):这是一个抽象类,提供给所有实际处理器进行继承。它拥有一个 HandleRequest 方法,用来接收需要处理的请求。

ConcreteHandler(具体处理器):这是一个实现了 handleRequest 方法的具体类。每一个具体处理器都维持一个引用,指向链中下一个具体处理器,需要检查它自身是否能处理这个请求,如果不能处理就会把请求传递给链中的下一个具体处理器。

3.2、代码实现案例

我们创建抽象类 AbstractLogger,带有详细的日志记录级别。然后我们创建三种类型的记录器,都扩展了 AbstractLogger。每个记录器消息的级别是否属于自己的级别,如果是则相应地打印出来,否则将不打印并把消息传给下一个记录器。

先来看一张日志记录的类图结构,如图1-2:
2d2a5e7b914a4135af122eb45096e9df.png

图1-2


1)先来创建一个抽象处理器类 AbstaractLogger

    AbstractLogger.java

    package com.zhaoyanfei.designpattern.chainOfResponsibilityPattern;
    /**
     * 
     * @Date 2022年10月5日
     * @author zhaoYanFei
     *
     */
    public abstract class AbstractLogger {
     
        public static int INFO = 1;
        public static int DEBUG = 2;
        public static int ERROR = 3;
         
        protected int level;
         
        //责任链中的下一个元素
        protected AbstractLogger nextLogger;
         
        public void setNextLogger(AbstractLogger nextLogger){
            this.nextLogger = nextLogger;
        }
         
        public void logMessage(int level, String message){
             if(this.level <= level){
                 write(message);
             }
             if(nextLogger !=null){
                nextLogger.logMessage(level, message);
             }
       }
         
       abstract protected void write(String message);
        
    }

这个基类中我们有设置下一个责任处理器的方法 setNextLogger 方法。

2)创建一个继承了基类的 对象处理器 ConsoleLogger

ConsoleLogger .java
    package com.zhaoyanfei.designpattern.chainOfResponsibilityPattern;
     
    public class ConsoleLogger extends AbstractLogger {
     
        public ConsoleLogger(int level){
            this.level = level;
        }
        
        @Override
        protected void write(String message) {
            System.out.println("Standard Console::Logger: " + message);
        }
     
    }

3)类似的再创建继承了基类 AbstractLogger 的两个处理器,FileLogger 和 ErrorLogger

 FileLogger.java
    package com.zhaoyanfei.designpattern.chainOfResponsibilityPattern;
     
    public class FileLogger extends AbstractLogger {
     
        public FileLogger(int level){
            this.level = level;
        }
        
        @Override
        protected void write(String message) {
            System.out.println("File::Logger: " + message);
        }
     
    }
ErrorLogger.java

package com.zhaoyanfei.designpattern.chainOfResponsibilityPattern;
 
public class ErrorLogger extends AbstractLogger {
 
    public ErrorLogger(int level){
        this.level = level;
    }
    
    @Override
    protected void write(String message) {
        System.out.println("Error Console::Logger: " + message);
    }
 
}
4)客户端构建一个处理器的责任链请求示例 ChainPatternDemo。

创建不同类型的记录器,赋予它们不同的错误级别;

并在每个记录器中设置下一个记录器,每个记录器中的下一个记录器代表的是链的一部分。

     ChainPatternDemo.java
package com.zhaoyanfei.designpattern.chainOfResponsibilityPattern;
 
/**
 * 客户端构建一个处理器的责任链
 * @Date 2022年10月5日
 * @author zhaoYanFei
 *
 */
public class ChainPatternDemo {
 
    private static AbstractLogger getChainOfLoggers() {
        //先实例化不同级别的日志对象
        AbstractLogger errorLogger = new ErrorLogger(AbstractLogger.ERROR);
        AbstractLogger fileLogger = new FileLogger(AbstractLogger.DEBUG);
        AbstractLogger consoleLogger = new ConsoleLogger(AbstractLogger.INFO);
        //error 级别最高,初始error日志处理器处理,如果不能处理,丢给下一个处理器
        errorLogger.setNextLogger(fileLogger);
        //以此类推,上一个FileLogger 不能处理的传递给ConsoleLogger对象处理
        fileLogger.setNextLogger(consoleLogger);
        return errorLogger;
    }
    
    public static void main(String[] args) {
        //构建责任链
        AbstractLogger chainOfLoggers = getChainOfLoggers();
        
        chainOfLoggers.logMessage(AbstractLogger.INFO, "This is an info information.");
        chainOfLoggers.logMessage(AbstractLogger.DEBUG, "This is an debug information.");
        chainOfLoggers.logMessage(AbstractLogger.ERROR, "This is an error information.");
    }
}
 5)查看运行结果

894b6407c0cd48d1816681594d7ab86e.png

# 4、责任链的优缺点 ## 4.1、优点 1、降低耦合度。它将请求的发送者和接收者解耦。 2、简化了对象。使得对象不需要知道链的结构。 3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。 4、增加新的请求处理类很方便。 ## 4.2、缺点 1、不能保证请求一定被接收。 2、系统性能将受到一定影响,而且可能会造成循环调用。 3、运行期特征不易观察,排除问题不太友好。 # 5、责任链模式的应用场景 1、事件处理器,例如 js 中的事件冒泡;大部分图形用户界面框架使用责任链模式来处理事件。 2、日志处理器 3、JAVA WEB 中 servlet ,在 Java 中,javax.servlet.Filter 被用来过滤请求或者响应。 doFilter 方法把过滤器链作为一个参数接收,它能够传递请求。 4、JAVA WEB 中 Apache Tomcat 对 Encoding 的处理,Struts2 的拦截器等等。 # 6、结语
相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
2月前
|
设计模式 JavaScript Scala
Kotlin - 改良设计模式 - 责任链模式
Kotlin - 改良设计模式 - 责任链模式
55 9
|
28天前
|
设计模式 JavaScript Scala
Kotlin教程笔记(55) - 改良设计模式 - 责任链模式
Kotlin教程笔记(55) - 改良设计模式 - 责任链模式
36 0
|
2月前
|
设计模式 监控 算法
Java设计模式梳理:行为型模式(策略,观察者等)
本文详细介绍了Java设计模式中的行为型模式,包括策略模式、观察者模式、责任链模式、模板方法模式和状态模式。通过具体示例代码,深入浅出地讲解了每种模式的应用场景与实现方式。例如,策略模式通过定义一系列算法让客户端在运行时选择所需算法;观察者模式则让多个观察者对象同时监听某一个主题对象,实现松耦合的消息传递机制。此外,还探讨了这些模式与实际开发中的联系,帮助读者更好地理解和应用设计模式,提升代码质量。
Java设计模式梳理:行为型模式(策略,观察者等)
|
2月前
|
设计模式 JavaScript Scala
Kotlin - 改良设计模式 - 责任链模式
本教程详细讲解了Kotlin语法,适合需要深入了解Kotlin的开发者。对于希望快速上手Kotlin的读者,推荐查阅“简洁”系列教程。本文通过学生会经费申请的例子,介绍了责任链模式及其在Kotlin中的实现,并使用偏函数进行了改进,使代码更加简洁和灵活。
16 0
|
2月前
|
设计模式 JavaScript Scala
Kotlin - 改良设计模式 - 责任链模式
Kotlin - 改良设计模式 - 责任链模式
39 0
|
2月前
|
设计模式 JavaScript Scala
Kotlin学习笔记 - 改良设计模式 - 责任链模式
Kotlin学习笔记 - 改良设计模式 - 责任链模式
44 0
|
3月前
|
设计模式 缓存 监控
Java设计模式-责任链模式(17)
Java设计模式-责任链模式(17)
|
2月前
|
设计模式 JavaScript Scala
Kotlin教程笔记(55) - 改良设计模式 - 责任链模式
Kotlin教程笔记(55) - 改良设计模式 - 责任链模式
27 0
|
4月前
|
设计模式 算法 Java
【十六】设计模式~~~行为型模式~~~策略模式(Java)
文章详细介绍了策略模式(Strategy Pattern),这是一种对象行为型模式,用于定义一系列算法,将每个算法封装起来,并使它们可以相互替换。策略模式让算法独立于使用它的客户而变化,提高了系统的灵活性和可扩展性。通过电影院售票系统中不同类型用户的打折策略案例,展示了策略模式的动机、定义、结构、优点、缺点以及适用场景,并提供了Java代码实现和测试结果。
【十六】设计模式~~~行为型模式~~~策略模式(Java)
|
4月前
|
设计模式 网络协议 Java
【十五】设计模式~~~行为型模式~~~状态模式(Java)
文章详细介绍了状态模式(State Pattern),这是一种对象行为型模式,用于处理对象在其内部状态改变时的行为变化。文中通过案例分析,如银行账户状态管理和屏幕放大镜工具,展示了状态模式的应用场景和设计方法。文章阐述了状态模式的动机、定义、结构、优点、缺点以及适用情况,并提供了Java代码实现和测试结果。状态模式通过将对象的状态和行为封装在独立的状态类中,提高了系统的可扩展性和可维护性。
【十五】设计模式~~~行为型模式~~~状态模式(Java)