【设计模式】第十五章:责任链模式详解及应用案例

这篇具有很好参考价值的文章主要介绍了【设计模式】第十五章:责任链模式详解及应用案例。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

系列文章

【设计模式】七大设计原则
【设计模式】第一章:单例模式
【设计模式】第二章:工厂模式
【设计模式】第三章:建造者模式
【设计模式】第四章:原型模式
【设计模式】第五章:适配器模式
【设计模式】第六章:装饰器模式
【设计模式】第七章:代理模式
【设计模式】第八章:桥接模式
【设计模式】第九章:外观模式 / 门面模式
【设计模式】第十章:组合模式
【设计模式】第十一章:享元模式
【设计模式】第十二章:观察者模式
【设计模式】第十三章:模板方法模式
【设计模式】第十四章:策略模式
【设计模式】第十五章:责任链模式
【设计模式】第十六章:迭代器模式
【设计模式】第十七章:状态模式
【设计模式】第十八章:备忘录模式
【设计模式】第十九章:访问者模式
【设计模式】第二十章:解释器模式
【设计模式】第二十一章:命令模式
【设计模式】第二十二章:中介者模式



一、定义

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


二、角色分类

抽象处理者(Handler)

定义了处理请求的接口或者抽象类,并提供了处理请求的的方法和设置下一个处理者的方法

具体处理者(Concrete Handler)

它是抽象处理者的子类,可以处理用户请求,在具体处理者类中实现了抽象处理者中定义的抽象请求处理方法,在处理请求之前需要进行判断,看是否有相应的处理权限,如果可以处理请求就处理它,否则将请求转发给后继者;在具体处理者中可以访问链中下一个对象,以便请求的转发

客户角色(Client)

具体调用方法的角色


三、实现方式

UML图

【设计模式】第十五章:责任链模式详解及应用案例,设计模式,设计模式,责任链模式

具体实现

假如我们想用责任链模式实现一个请假流程,可以这么来实现

抽象处理者(Handler)

@Data
public abstract class Handler {
  // 处理者姓名
  protected String processorName;
  // 下一个处理者
  protected Handler nextHandler

  public Handler (String processorName) {
    this.processorName = processorName;
  }

  /**
   * 处理请假抽象方法
   * @param name 请假人姓名
   * @param numOfDays 请假天数
   */
  public abstract boolean process(String name, int numOfDays);
}

具体处理者(Concrete Handler)

/**
 * 组长
 */
@Slf4j
public class TeamLeaderHandler extends Handler {
  public TeamLeaderHandler(String processorName) {
    this.processorName = processorName;
  }

  @Override
  public boolean process(String name, int numOfDays) {
    // 创建随机数,值大于3则为通过,否则为不通过
    boolean res = (new Random().nextInt(10)) > 3;
    String result = res ? "通过" : "驳回";
    log.info("组长<{}>审批<{}>的请假申请,请假天数为:<{}>天,审批结果为:<{}>", processorName, name, numOfDays, result);

    if(Boolean.FALSE.equals(res)) {
      // 审批驳回
      return false;
    } else if (numOfDays < 3){
      // 请假通过且请假天数小于3天时直接通过
      return true;
    }
    // 若审批通过且请假天数大于等于3天时提交给下一个审批人
    return nextHandler.process(name, numOfDays);
  }
}

/**
 * 部门经理
 */
@Slf4j
public class DepartmentManagerHandler extends Handler {
  public DepartmentManagerHandler(String processorName) {
    super(name);
  }

  @Override
  public boolean process(String name, int numOfDays) {
    // 创建一个随机数 当随机数大于3时为通过,否则为不通过
    boolean res = (new Random().nextInt(10)) > 3;
    String result = result ? "通过" : "驳回";
    log.info("部门经理<{}>审批<{}>的请假申请,请假天数为:<{}>天,审批结果为:<{}>", processorName, name, numOfDays, result);

    if(Boolean.FALSE.equals(res)) {
      // 审批驳回
      return false;
    } else if (numOfDays <7) {
      // 审批通过且审批天数小于7天时直接通过
      return true;
    }
    // 批准天数大于等于7天时提交给下一个审批人
    return nextHandler.process(name, numOfDays);
  }

  /**
   * CEO
   */
  @Slf4j
  public class CEOHandler extends Handler {
    public CEOHandler(String processorName) {
      super(name);
    }

    public boolean process(String name, int numOfDays) {
      // 创建一个随机数,大于3则为通过,否则为驳回
      boolean res = (new Random().nextInt(10)) > 3;
      String result = res ? "通过" : "驳回";
      log.info("CEO<{}>审批<{}>的请假申请,请假天数为:<{}>天,审批结果为:<{}>", processorName, name, numOfDays, result);

      if(Boolean.FALSE.equals(res)) {
        //驳回
        return false;
      }
      return true;
    } 
  } 
}

客户角色(Client)

public class Client {
  public static void main(String[] args) {
    Handler zhangsan = new TeamLeaderHandler("张三");
    Handler lisi = new DepartmentManagerHandler("李四");
    Handler wangwu = new CEOHandler("王五");

    // 创建责任链
    zhangsan.setNextHandler(lisi);
    lisi.setNextHandler(wangwu);

    // 发起请假申请
    boolean res1 = zhangsan.process("小A", 2);
    System.out.println("最终结果:" + res);

    boolean res1 = zhangsan.process("小B", 5);
    System.out.println("最终结果:" + res);
    
    boolean res1 = zhangsan.process("小C", 10);
    System.out.println("最终结果:" + res);
  }
}

运行结果

组长<张三>审批<小A>的请假申请,请假天数为:<2>天,审批结果为:<通过>
最终结果:true

部门经理<李四> 审批 <小B> 的请假申请,请假天数: <5>天 ,审批结果:<不通过> 
最终结果:false

组长<张三> 审批 <小C> 的请假申请,请假天数: <10> 天,审批结果:<通过> 
部门经理<李四> 审批 <小C> 的请假申请,请假天数: <10> 天,审批结果:<通过> 
CEO<王五> 审批 <小C> 的请假申请,请假天数: <10> 天,审批结果:<通过> 
最终结果:true

四、应用场景

以下部分内容摘自菜鸟教程

意图: 避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。

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

何时使用: 在处理消息的时候以过滤很多道。

如何解决: 拦截的类都实现统一接口。

关键代码: Handler 里面聚合它自己,在 HandlerRequest 里判断是否合适,如果没达到条件则向下传递,向谁传递之前 set 进去。

应用实例:

  1. 红楼梦中的"击鼓传花"。
  2. JS 中的事件冒泡。
  3. JAVA WEB 中 Apache Tomcat 对 Encoding 的处理,Struts2 的拦截器,jsp servlet 的 Filter。

使用场景:

  1. 有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。
  2. 在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
  3. 可动态指定一组对象处理请求。

注意事项: 在 JAVA WEB 中遇到很多应用。


五、优缺点

优点

  1. 降低耦合度。它将请求的发送者和接收者解耦。
  2. 简化了对象。使得对象不需要知道链的结构。
  3. 增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。
  4. 增加新的请求处理类很方便。

缺点

  1. 不能保证请求一定被接收。
  2. 系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。
  3. 可能不容易观察运行时的特征,有碍于除错。

推荐

关注博客和公众号获取最新文章

Bummon’s Blog | Bummon’s Home | 公众号文章来源地址https://www.toymoban.com/news/detail-538298.html

到了这里,关于【设计模式】第十五章:责任链模式详解及应用案例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java设计模式之责任链模式(UML类图分析+代码详解)

    大家好,我是一名在算法之路上不断前进的小小程序猿!体会算法之美,领悟算法的智慧~ 希望各位博友走过路过可以给我点个免费的赞,你们的支持是我不断前进的动力!! 加油吧!未来可期!! 本文将介绍java设计模式之责任链模式 OA系统采购审批需求 传统方案解决OA系

    2024年02月06日
    浏览(38)
  • 第十五章行为性模式—命令模式

    行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象无法单独完成的任务,它涉及算法与对象间职责的分配。行为型模式分为类行为模式和对象行为模式: 类行为模式:采用继承机制来在类间分派行为 对象行为模式:

    2024年02月07日
    浏览(40)
  • 【设计模式】第十一章:享元模式详解及应用案例

    【设计模式】七大设计原则 【设计模式】第一章:单例模式 【设计模式】第二章:工厂模式 【设计模式】第三章:建造者模式 【设计模式】第四章:原型模式 【设计模式】第五章:适配器模式 【设计模式】第六章:装饰器模式 【设计模式】第七章:代理模式 【设计模式

    2024年02月13日
    浏览(38)
  • 【新版系统架构】第十五章-面向服务架构设计理论与实践

    软考-系统架构设计师知识点提炼-系统架构设计师教程(第2版) 第一章-绪论 第二章-计算机系统基础知识(一) 第二章-计算机系统基础知识(二) 第三章-信息系统基础知识 第四章-信息安全技术基础知识 第五章-软件工程基础知识(一) 第五章-软件工程基础知识(需求工

    2024年02月16日
    浏览(43)
  • 【设计模式】第十二章:观察者模式详解及应用案例

    【设计模式】七大设计原则 【设计模式】第一章:单例模式 【设计模式】第二章:工厂模式 【设计模式】第三章:建造者模式 【设计模式】第四章:原型模式 【设计模式】第五章:适配器模式 【设计模式】第六章:装饰器模式 【设计模式】第七章:代理模式 【设计模式

    2024年02月13日
    浏览(40)
  • 《设计模式》责任链模式

    定义 : 责任链模式将链中每一个节点都看成一个对象,并且将这些节点对象连成一条链,请求会沿着这条链进行传递,直到有对象处理它为止,这使得多个对象都有机会接收请求,避免了请求发送者和接收者之间的耦合。 属于 行为型 设计模式。 责任链模式的角色组成 :

    2024年02月13日
    浏览(42)
  • 【设计模式】责任链模式

    顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。 在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处

    2024年02月12日
    浏览(37)
  • 设计模式——责任链模式

    使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,知道有对象处理它为止。 优点 能将请求和处理分开。请求者可以不用知道是谁处理的,处理者可以不用知道请求的全貌,两者解耦提高系

    2024年02月15日
    浏览(40)
  • 设计模式—责任链模式

    一、待解决问题 : 减少代码中 if else 语句,降低代码圈复杂度或深度,增强可读性。 1、需求背景: 采购订单创建,需要验证采购员、物料、供应商、供应商的银行账号等信息。如采购员权限到期、或供应商失效等问题,都无法下单。 2、代码如下: 学习使用责任链模式后

    2024年02月10日
    浏览(44)
  • 设计模式:责任链模式

    责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它允许多个对象按照顺序处理请求,直到其中一个对象能够处理该请求为止。责任链模式将请求发送者和接收者解耦,使得多个对象都有机会处理请求,同时避免了请求发送者与接收者之间的直接耦合关系。 在

    2024年02月07日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包