码仔漫画:做个审批流程,被领导怒怼“什么玩意儿”!

互联网全栈架构

共 5532字,需浏览 12分钟

 ·

2021-06-13 07:52

目录


  • 故事

  • 责任链简介

  • 代码类图

  • 代码实现

  • 责任链优缺点

  • 应用场景

  • 思维导图


故事

传统if-else判断方式。


public class LeaveApproval {
public static void main(String[] args) {
    ExpenseReimbursement maNiuApply = new ExpenseReimbursement();
     maNiuApply.setName("Ma Niu");
    maNiuApply.setAmount(-100);

    if (maNiuApply.getAmount() < 0 ) {
        System.out.println("Amount error!");
    } else if (maNiuApply.getAmount() <= 500) {
        projectManagerHandle(maNiuApply);
     } else if (maNiuApply.getAmount() <= 1000) {
        departmentManagerHandle(maNiuApply);
    }else {
        managingDirectorHandle(maNiuApply);
     }
 }

  public static void projectManagerHandle(ExpenseReimbursement expense) {
     System.out.println("Project manager approved " + expense.getAmount());
   }

  public static void departmentManagerHandle(ExpenseReimbursement expense) {
    System.out.println("Department manager approved " + expense.getAmount());
   }

  public static void managingDirectorHandle(ExpenseReimbursement expense) {
    System.out.println("Managing director approved " + expense.getAmount());
   }
}

       

       


简介


责任链模式(Chain of Responsibility),又名职责链模式,是一种对象行为型模式。定义:为了避免请求发送者与多个请求处理者耦合在一起,于是将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。


责任链模式的本质是:将请求的发送者和请求的处理者解耦,让请求在处理链中能进行传递,由具体的处理者完成处理。


代码类图


                

抽象处理者(Handler):封装处理请求方法的接口,主要方法有:抽象处理方法和后继连接节点。


具体处理者(Concrete Handler):抽象处理者的具体实现。在抽象处理方法的实现中,判断是否处理本次请求。如果能处理就完成请求;如果不能处理就将请求传递给链上的下一个处理者。


客户类(Client):首先,创建各个具体处理者,并将他们组成处理链。之后,将请求提交给链头的具体处理者。


代码实现


public class ChainOfResponsibilityPattern {

public static void main(String[] args) {
    //组装责任链
    Handler handler1 = new ConcreteHandler1();
    Handler handler2 = new ConcreteHandler2();
    handler1.setNext(handler2);
    //提交请求
    handler1.handleRequest("two");
   }
}


//抽象处理者角色
abstract class Handler {

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

   public Handler getNext() {
      return next;
   }

   //处理请求的方法
   public abstract void handleRequest(String request);
}


//具体处理者角色1
class ConcreteHandler1 extends Handler {
   @Override
   public void handleRequest(String request)
{
       if (request.equals("one")) {
         System.out.println("ConcreteHandler1 handler!");
       } else {
       if (getNext() != null) {
           getNext().handleRequest(request);
       } else {
           System.out.println("None handler!");
           }
       }
   }
}


//具体处理者角色2
class ConcreteHandler2 extends Handler {
   @Override
   public void handleRequest(String request)
{
      if (request.equals("two")) {
            System.out.println("ConcreteHandler2 handler!");
      } else {
      if (getNext() != null) {
         getNext().handleRequest(request);
      } else {
        System.out.println("None handler!");
      }
      }
   }
}


优点


  1. 降低了对象之间的耦合度。该模式使得一个对象无须知道到底是哪一个对象处理其请求以及链的结构,发送者和接收者也无须拥有对方的明确信息。

  2. 满足开闭原则。针对新的需求,可以灵活的增加新的具体处理者,系统可扩展性灵活

  3. 增强了给对象指派职责的灵活性。当工作流程发生变化,可以动态地改变链内的成员或者调动它们的次序,也可动态地新增或者删除责任。

  4. 简化了对象之间的连接。每个对象只需保持一个指向其后继者的引用,避免了使用众多的 if 或者 if···else 语句。

  5. 职责明确。每个类只需要处理自己该处理的工作,不该处理的传递给下一个对象完成,符合类的单一职责原则。



缺点


  1. 不能保证每个请求一定被处理。由于一个请求没有明确的接收者,所以不能保证它一定会被处理,该请求可能一直传到链的末端都得不到处理。

  2. 对比较长的职责链,请求的处理可能涉及多个处理对象,系统性能将受到一定影响。

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


应用场景


  • 多个对象可以处理一个请求,但具体由哪个对象处理该请求在运行时自动确定。

  • 可动态指定一组对象处理请求,或添加新的处理者。

  • 需要在不明确指定请求处理者的情况下,向多个处理者中的一个提交请求。


扩展

职责链模式存在以下两种扩展情况:

  • 纯的职责链模式:一个请求必须被某一个处理者对象所接收,且一个具体处理者对某个请求的处理只能采用以下两种行为之一:自己处理(承担责任);把责任推给下家处理。

  • 不纯的职责链模式:允许出现某一个具体处理者对象在承担了请求的一部分责任后又将剩余的责任传给下家的情况,且一个请求可以最终不被任何接收端对象所接收。


与装饰者模式的异同

       


思维导图

       


推荐阅读:
亿级系统的Redis缓存如何设计
学会这10个设计原则,离架构师又进一步
知乎高赞:为什么Kafka需要Leader而Redis不需要
由浅入深逐步讲解Java并发的半壁江山AQS
再有人问你MySQL索引原理,就把这篇文章甩给他!

互联网全栈架构

浏览 31
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报