笔头云 笔头云
首页
设计模式
SQL教程
Redis
归档
关于
友链

笔头云

非淡泊无以明志,非宁静无以致远。
首页
设计模式
SQL教程
Redis
归档
关于
友链
  • 设计原则
  • 设计模式
  • 单例模式
  • 工厂模式
  • 建造者模式
  • 原型模式
  • 适配器模式
  • 代理模式
  • 装饰器模式
  • 门面模式
  • 桥接模式
  • 享元模式
  • 组合模式
  • 策略模式
  • 模板方法模式
  • 观察者模式
  • 责任链模式
    • 定义
    • 结构
    • 优点
    • 缺点
    • 应用场景
    • 示例代码
  • 状态模式
  • 迭代器模式
  • 访问者模式
  • 中介模式
  • 命令模式
  • 解释器模式
  • 备忘录模式
  • 设计模式
笔头云
2023-10-25
目录

责任链模式

# 责任链模式

# 定义

责任链模式,使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。每个处理器对象都有机会处理请求,也可以选择将请求传递给下一个处理器。

# 结构

抽象处理者(Handler)角色:定义一个处理请求的接口,包含抽象处理方法和一个后继连接。
具体处理者(Concrete Handler)角色:实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者。
客户类(Client)角色:创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程。

责任链模式

- img: https://bitouyun.com/images/design-pattern/resposibility.png
  link: https://bitouyun.com/images/design-pattern/resposibility.png
  name: 责任链模式
1
2
3

# 优点

降低了对象之间的耦合度。该模式使得一个对象无须知道到底是哪一个对象处理其请求以及链的结构,发送者和接收者也无须拥有对方的明确信息。
增强了系统的可扩展性。可以根据需要增加新的请求处理类,满足开闭原则。
责任分担。每个类只需要处理自己该处理的工作,不该处理的传递给下一个对象完成,明确各类的责任范围,符合类的单一职责原则。

# 缺点

职责链建立的合理性要靠客户端来保证,增加了客户端的复杂性,可能会由于职责链的错误设置而导致系统出错,如可能会造成循环调用。

# 应用场景

有多个对象可以处理一个请求,哪个对象处理该请求由运行时刻自动确定。
可动态指定一组对象处理请求,或添加新的处理者。

# 示例代码

场景

公司请假: 1天内需要组长同意;请假3天内需要部门经理同意;请求7天内需要总经理同意。

    /**
     * 抽象处理者
     * 定义了处理请求的接口,并持有下一个处理器的引用,通常包含一个处理方法(如handleRequest()),用于处理请求或将请求传递给下一个处理者。
     */
    public abstract class Handler {
      protected Handler next;
    
      /**
       * 设置下一个处理者
       * @param next
       */
      public void setNext(Handler next) {
        this.next = next;
      }
    
      public abstract void handleRequest(Leave leave);
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    /**
     * 请假实体类
     */
    @Data
    public class Leave {
      // 姓名
      private String name;
      // 请假天数
      private int day;
      // 内容
      private String content;
    
      public Leave(String name, int day, String content) {
        this.name = name;
        this.day = day;
        this.content = content;
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    /**
     * 组长处理者
     * 具体处理者,实现了抽象处理者的接口,负责处理特定类型的请求。如果自己无法处理请求,可以将请求传递给下一个处理者。
     */
    @Slf4j
    public class GroupLeader extends Handler {
      @Override
      public void handleRequest(Leave leave) {
        if (leave.getDay() <= 1) {
          log.info("组长:{},请假{}天,批准了.", leave.getName(), leave.getDay());
        }else if(next !=null){
          next.handleRequest(leave);
        }
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    /**
     * 部门经理处理者
     * 具体处理者,实现了抽象处理者的接口,负责处理特定类型的请求。如果自己无法处理请求,可以将请求传递给下一个处理者。
     */
    @Slf4j
    public class DepartmentManager extends Handler {
    
      @Override
      public void handleRequest(Leave leave) {
        if(leave.getDay()<=3){
          log.info("部门经理:{},请假{}天,批准了.", leave.getName(), leave.getDay());
        }else if(next !=null) {
          next.handleRequest(leave);
        }
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    /**
     * 总经理处理者
     * 具体处理者,实现了抽象处理者的接口,负责处理特定类型的请求。如果自己无法处理请求,可以将请求传递给下一个处理者。
     */
    @Slf4j
    public class GeneralManager extends Handler {
      @Override
      public void handleRequest(Leave leave) {
        if (leave.getDay() <= 7) {
          log.info("总经理:{}请假{}天,批准了", leave.getName(), leave.getDay());
        } else if (next != null) {
          next.handleRequest(leave);
        }
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    /**
     * 测试类
     */
    public class Client {
      public static void main(String[] args) {
        // 创建处理者对象
        Handler groupLeader = new GroupLeader();
        DepartmentManager departmentManager = new DepartmentManager();
        GeneralManager generalManager = new GeneralManager();
    
        // 设置处理链
        groupLeader.setNext(departmentManager);
        departmentManager.setNext(generalManager);
    
        // 创建请假请求
        Leave zhangSan = new Leave("张三", 1, "郊游");
        Leave liSi = new Leave("李四", 3, "省内游");
        Leave wangWu = new Leave("王五", 7, "国内游");
    
        // 处理请假请求
        groupLeader.handleRequest(zhangSan);
        groupLeader.handleRequest(liSi);
        groupLeader.handleRequest(wangWu);
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    // Make sure to add code blocks to your code group
    #行为型模式#设计模式
    上次更新: 2023/11/17, 09:38:49
    观察者模式
    状态模式

    ← 观察者模式 状态模式→

    最近更新
    01
    FRP内网穿透docker部署 工具
    05-07
    02
    Office Util办公工具 工具
    01-14
    03
    Git常用命令
    01-16
    更多文章>
    Theme by Vdoing | Copyright © 2023-2025 鲁ICP备2023014898号 公安备案号:37020302372159
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式
    ×