【设计模式系列9】责任链模式

简介: 目前也工作了很长时间,实际项目中其实还没有真正去使用过责任链模式,也没有看别人用过,所以感觉这个模式比较小众。这篇文章没啥技术含量,纯粹写了个demo,记录一下这个模式的用法。

{5DP309A(I]$[WA1E{PUMPH.png

主要讲解责任链模式的实现方式,基于java。


前言


上半年写了8篇设计模式相关的文章,之所以又开始写这个系列,是因为这周看代码时,发现代码中标注的是“XX责任链”,当时怀疑是不是用的责任链模式,但是看了一会又不像,然后之前技术方案评审时,有一位同学也提到过这个设计模式,当时就想再拎出来瞅瞅,只是太懒了。

目前也工作了很长时间,实际项目中其实还没有真正去使用过责任链模式,也没有看别人用过,所以感觉这个模式比较小众。

这篇文章没啥技术含量,纯粹写了个demo,记录一下这个模式的用法。


定义


我们看一下责任链模式的定义:

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

在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。

在责任链模式中,客户只需要将请求发送到责任链上即可,无须关心请求的处理细节和请求的传递过程,所以责任链将请求的发送者和请求的处理者解耦了。


责任链模式


先创建一个抽象类,里面包括责任链等级,以及责任链的下一个元素:

public abstract class penguin {
    protected int level; // 责任链等级
    protected penguin nextPenguin; // 责任链中的下一个元素
    public void process(int level, String message) {
        if (level >= this.level) {
            // 如果输入的级别大于对象本身的级别,输出数据
            print(message);
        }
        if (this.nextPenguin != null) {
            // 如果存在下一个元素,就继续往下执行
            nextPenguin.process(level,message);
        }
    }
    public abstract void print(String message);
}

下面是实现的子类,为了简单期间,我直接标明每个子类的等级:

// 小企鹅子类
public class littlePenguin extends penguin {
    public littlePenguin() {
        this.level = 1;
    }
    @Override
    public void print(String message) {
        System.out.println("Little Penguin:" + message);
    }
}
// 中企鹅子类
public class middlePenguin extends penguin {
    public middlePenguin() {
        this.level = 2;
    }
    @Override
    public void print(String message) {
        System.out.println("Middle Penguin:" + message);
    }
}
// 大企鹅子类
public class bigPenguin extends penguin {
    public bigPenguin() {
        this.level = 3;
    }
    @Override
    public void print(String message) {
        System.out.println("Big Penguin:" + message);
    }
}

最后就是测试用例,我们先将三个子类串起来,类似于串糖葫芦,层级依次递进:

public class test {
    public static void main(String[] args) {
        littlePenguin penguin1 = new littlePenguin();
        middlePenguin penguin2 = new middlePenguin();
        bigPenguin penguin3 = new bigPenguin();
        penguin3.nextPenguin = penguin2;
        penguin2.nextPenguin = penguin1;
        penguin3.process(3, "print big/middle/small");
        penguin3.process(2, "print middle/small");
        penguin3.process(1, "print small");
    }
}

最后的输出结果:

Big Penguin:print big/middle/small
Middle Penguin:print big/middle/small
Little Penguin:print big/middle/small
Middle Penguin:print middle/small
Little Penguin:print middle/small
Little Penguin:print small

我们可以看到,当level=2时,只输出了Little Penguin和Middle Penguin,因为只有<=2的级别才能输出。当level=2时,就只输出了Little Penguin,满足责任链的场景。


优点 VS 缺点


优点:

  • 降低了对象之间的耦合度。该模式使得一个对象无须知道到底是哪一个对象处理其请求以及链的结构,发送者和接收者也无须拥有对方的明确信息。
  • 增强了系统的可扩展性。可以根据需要增加新的请求处理类,满足开闭原则。
  • 增强了给对象指派职责的灵活性。当工作流程发生变化,可以动态地改变链内的成员或者调动它们的次序,也可动态地新增或者删除责任。
  • 责任链简化了对象之间的连接。每个对象只需保持一个指向其后继者的引用,不需保持其他所有处理者的引用,这避免了使用众多的 if 或者 if···else 语句。
  • 责任分担。每个类只需要处理自己该处理的工作,不该处理的传递给下一个对象完成,明确各类的责任范围,符合类的单一职责原则。

感觉这个“责任分担”,给了我一些使用该模式的新思路,比如有2个任务,第一轮只处理第一个任务,第二轮处理第二个任务。

缺点:

  • 不能保证每个请求一定被处理。由于一个请求没有明确的接收者,所以不能保证它一定会被处理,该请求可能一直传到链的末端都得不到处理。
  • 对比较长的职责链,请求的处理可能涉及多个处理对象,系统性能将受到一定影响。
  • 职责链建立的合理性要靠客户端来保证,增加了客户端的复杂性,可能会由于职责链的错误设置而导致系统出错,如可能会造成循环调用。


应用场景


场景举例:一个请求有多个对象可以处理,但每个对象的处理条件或权限不同。例如,公司员工请假,可批假的领导有部门负责人、副总经理、总经理等,但每个领导能批准的天数不同,员工必须根据自己要请假的天数去找不同的领导签名,也就是说员工必须记住每个领导的姓名、电话和地址等信息,这增加了难度。这样的例子还有很多,如找领导出差报销、生活中的“击鼓传花”游戏等。

场景分类:

  • 有多个对象可以处理一个请求,哪个对象处理该请求由运行时刻自动确定。
  • 可动态指定一组对象处理请求,或添加新的处理者。
  • 在不明确指定请求处理者的情况下,向多个处理者中的一个提交请求。
相关文章
|
6月前
|
设计模式 Java
【设计模式系列笔记】责任链模式
责任链模式是一种行为设计模式,它允许你将请求沿着处理者链进行传递,直到有一个处理者能够处理它。每个处理者都有一个对下一个处理者的引用。责任链模式常用于处理请求的场景,例如在一个请求需要经过多个步骤或者多个对象来处理的情况下。
75 0
|
6月前
|
设计模式 Java
【设计模式】责任链模式
【设计模式】责任链模式
|
6月前
|
设计模式
【设计模式】责任链模式
【1月更文挑战第27天】【设计模式】责任链模式
|
15天前
|
设计模式 JavaScript Scala
Kotlin - 改良设计模式 - 责任链模式
Kotlin - 改良设计模式 - 责任链模式
51 9
|
3天前
|
设计模式 JavaScript Scala
Kotlin教程笔记(55) - 改良设计模式 - 责任链模式
Kotlin教程笔记(55) - 改良设计模式 - 责任链模式
10 0
|
14天前
|
设计模式 JavaScript Scala
Kotlin - 改良设计模式 - 责任链模式
本教程详细讲解了Kotlin语法,适合需要深入了解Kotlin的开发者。对于希望快速上手Kotlin的读者,推荐查阅“简洁”系列教程。本文通过学生会经费申请的例子,介绍了责任链模式及其在Kotlin中的实现,并使用偏函数进行了改进,使代码更加简洁和灵活。
11 0
|
17天前
|
设计模式 JavaScript Scala
Kotlin - 改良设计模式 - 责任链模式
Kotlin - 改良设计模式 - 责任链模式
35 0
|
24天前
|
设计模式 JavaScript Scala
Kotlin学习笔记 - 改良设计模式 - 责任链模式
Kotlin学习笔记 - 改良设计模式 - 责任链模式
42 0
|
2月前
|
设计模式 缓存 监控
Java设计模式-责任链模式(17)
Java设计模式-责任链模式(17)
|
27天前
|
设计模式 JavaScript Scala
Kotlin教程笔记(55) - 改良设计模式 - 责任链模式
Kotlin教程笔记(55) - 改良设计模式 - 责任链模式
24 0

热门文章

最新文章

  • 1
    《手把手教你》系列基础篇(九十四)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-下篇(详解教程)
    44
  • 2
    C++一分钟之-C++中的设计模式:单例模式
    51
  • 3
    《手把手教你》系列基础篇(九十三)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-上篇(详解教程)
    36
  • 4
    《手把手教你》系列基础篇(九十二)-java+ selenium自动化测试-框架设计基础-POM设计模式简介(详解教程)
    59
  • 5
    Java面试题:结合设计模式与并发工具包实现高效缓存;多线程与内存管理优化实践;并发框架与设计模式在复杂系统中的应用
    54
  • 6
    Java面试题:设计模式在并发编程中的创新应用,Java内存管理与多线程工具类的综合应用,Java并发工具包与并发框架的创新应用
    39
  • 7
    Java面试题:如何使用设计模式优化多线程环境下的资源管理?Java内存模型与并发工具类的协同工作,描述ForkJoinPool的工作机制,并解释其在并行计算中的优势。如何根据任务特性调整线程池参数
    49
  • 8
    Java面试题:请列举三种常用的设计模式,并分别给出在Java中的应用场景?请分析Java内存管理中的主要问题,并提出相应的优化策略?请简述Java多线程编程中的常见问题,并给出解决方案
    102
  • 9
    Java面试题:设计模式如单例模式、工厂模式、观察者模式等在多线程环境下线程安全问题,Java内存模型定义了线程如何与内存交互,包括原子性、可见性、有序性,并发框架提供了更高层次的并发任务处理能力
    74
  • 10
    Go语言设计模式:使用Option模式简化类的初始化
    71