责任链模式(Java版)

简介: 项目背景小明操作公司的采购员,需要去采购一批电脑,通过对市场的调研之后,需要提交申请走审批流程拨款购买。审批的决策因素是采用电脑的总价。小于5000,组长审批就ok了,5000-10000需要部长审批,10000-50000需要副总裁审批,50000以上需要总裁审批。

项目背景


小明操作公司的采购员,需要去采购一批电脑,通过对市场的调研之后,需要提交申请走审批流程拨款购买。审批的决策因素是采用电脑的总价。小于5000,组长审批就ok了,5000-10000需要部长审批,10000-50000需要副总裁审批,50000以上需要总裁审批。

考虑到扩展性,我们下面思考下如何设计?

第一,影响决策因素:价格

第二,决策级别:组长、部长、副总、总裁

接下来,我们责任链模式隆重登场了。


什么是责任链模式?


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


责任链的意图


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


主要解决的问题


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


代码示例


下面示例代码走起,首先定义采购对象:

// 采购
public class PurchaseRequest {
    // 采购类型
    private int type = 0;
    // 采购数量
    private int number = 0;
    // 采购单价
    private float price = 0;
    // 采购ID
    private int id = 0;
    public PurchaseRequest(int type, int number, float price) {
        this.type = type;
        this.number = number;
        this.price = price;
    }
    public int getType() {
        return type;
    }
    public float getSum() {
        return number * price;
    }
    public int getId() {
        return (int) (Math.random() * 1000);
    }
}
复制代码

然后抽象出来一个审批父类:

@Getter
@Setter
public abstract class Approver {
    // 下一个审批者
    protected Approver successor;
    private String name;
    public Approver(String name) {
        this.name=name;
    }
    public abstract void processRequest(PurchaseRequest request);
}
复制代码

下面依次实现组长、部长、副总裁、总裁审批:

package com.lgd.design.chain;
// 组审批
public class GroupApprover extends Approver {
    public GroupApprover(String Name) {
        super(Name + " GroupLeader");
    }
    @Override
    public void processRequest(PurchaseRequest request) {
        if (request.getSum() < 5000) {
            System.out.println("**This request " + request.getId() + " will be handled by " + this.getName() + " **");
        } else {
            successor.processRequest(request);
        }
    }
}
复制代码
package com.lgd.design.chain;
// 部门审批
public class DepartmentApprover extends Approver {
  public DepartmentApprover(String Name) {
    super(Name + " DepartmentLeader");
  }
  @Override
  public void processRequest(PurchaseRequest request) {
    if ((5000 <= request.getSum()) && (request.getSum() < 10000)) {
      System.out.println("**This request " + request.getId() + " will be handled by " + this.getName() + " **");
    } else {
      successor.processRequest(request);
    }
  }
}
复制代码
package com.lgd.design.chain;
// 副总裁审批
public class VicePresidentApprover extends Approver {
  public VicePresidentApprover(String name) {
    super(name + " Vice President");
  }
  @Override
  public void processRequest(PurchaseRequest request) {
    if ((10000 <= request.getSum()) && (request.getSum() < 50000)) {
      System.out.println("**This request " + request.getId() + " will be handled by " + this.getName() + " **");
    } else {
      successor.processRequest(request);
    }
  }
}
复制代码
package com.lgd.design.chain;
// 总裁审批
public class PresidentApprover extends Approver {
    public PresidentApprover(String Name) {
        super(Name + " President");
    }
    @Override
    public void processRequest(PurchaseRequest request) {
        if (50000 <= request.getSum()) {
            System.out.println("**This request " + request.getId() + " will be handled by " + this.getName() + " **");
        } else {
            successor.processRequest(request);
        }
    }
}
复制代码

最后测试审批流程:

package com.lgd.design.chain;
public class MainTest {
    public static void main(String[] args) {
        Approver groupApprover = new GroupApprover("Tom");
        Approver departmentApprover = new DepartmentApprover("Jerry");
        Approver vicePresidentApprover = new VicePresidentApprover("Kate");
        Approver presidentApprover = new PresidentApprover("Bush");
        groupApprover.setSuccessor(vicePresidentApprover);
        departmentApprover.setSuccessor(presidentApprover);
        vicePresidentApprover.setSuccessor(departmentApprover);
        presidentApprover.setSuccessor(groupApprover);
        vicePresidentApprover.processRequest(new PurchaseRequest(1, 100, 40));
        vicePresidentApprover.processRequest(new PurchaseRequest(2, 200, 40));
        vicePresidentApprover.processRequest(new PurchaseRequest(3, 300, 40));
        vicePresidentApprover.processRequest(new PurchaseRequest(4, 400, 140));
    }
}
复制代码

运行结果:

**This request 331 will be handled by Tom GroupLeader **

**This request 504 will be handled by Jerry DepartmentLeader **

**This request 309 will be handled by Kate Vice President **

**This request 473 will be handled by Bush President **

总结


优点:

  • 将请求的发送者和接收者解耦,使多个对象都有机会处理这个请求
  • 可以简化对象,因为它无须知道链的结构
  • 可以动态地增加或删减处理请求的链结构

缺点:

  • 请求从链的开头进行遍历,对性能有一定的损耗
  • 并不保证请求一定被处理

适用场合:

  • 有多个对象可以处理一个请求
  • 不明确接收者的情况
  • 有序、无序链,线型、树形、环形链

责任链模式和状态模式主要区别:

  • 责任链模式注重请求的传递
  • 状态模式注重对象状态的转换


相关文章
|
9月前
|
设计模式 Java
Java责任链模式
Java责任链模式
71 0
|
5月前
|
设计模式 缓存 监控
Java设计模式-责任链模式(17)
Java设计模式-责任链模式(17)
|
8月前
|
设计模式 Java 中间件
深入探索Java设计模式:责任链模式解析与实践
深入探索Java设计模式:责任链模式解析与实践
74 0
|
8月前
|
设计模式 Java
Java设计模式之责任链模式详解
Java设计模式之责任链模式详解
|
9月前
|
设计模式 Java
【设计模式】JAVA Design Patterns——Chain of responsibility(责任链模式)
【设计模式】JAVA Design Patterns——Chain of responsibility(责任链模式)
|
9月前
|
设计模式 Java
23种设计模式,责任链模式的概念优缺点以及JAVA代码举例
【4月更文挑战第7天】责任链模式是一种行为设计模式,它允许将请求沿着处理者链进行传递,直到有对象处理该请求为止。这种模式提供了一种解耦请求的发送者和接收者之间的方式,通过给多个对象处理一个请求的机会,减少了对象间的耦合度。
64 1
|
9月前
|
设计模式 Java
Java责任链模式
Java责任链模式
60 0
|
9月前
|
设计模式 Java
Java设计模式【十四】:责任链模式
Java设计模式【十四】:责任链模式
62 0
|
设计模式 Java
深入Java设计模式之责任链模式
深入Java设计模式之责任链模式
137 0
深入Java设计模式之责任链模式
|
设计模式 Java 应用服务中间件
【设计模式——学习笔记】23种设计模式——职责链/责任链模式(Chain of Responsibility)(原理讲解+应用场景介绍+案例介绍+Java代码实现)
【设计模式——学习笔记】23种设计模式——职责链/责任链模式(Chain of Responsibility)(原理讲解+应用场景介绍+案例介绍+Java代码实现)
190 0