赞
踩
以学校采购审批为例,不同金额的采购需要不同人员的审批
收到请求后,通过不同的金额调用对应的审批方法
Client会使用到分支判断(比如switch)来对不同的采购请求处理, 这样就存在如下问题:
(1)如果各个级别的人员审批金额发生变化,客户端的也需要变化
(2)客户端必须明确知道有多少个审批级别和访问
这样对一个采购请求进行处理和Approver(审批人)就存在强耦合关系,不利于代码的扩展和维护。故引出职责链模式。
职责链模式(Chain of Responsibility Pattern),又叫责任链模式,为请求创建了一个接收者对象的链,属于行为型模式。这种模式对请求的发送者和接收者进行解耦。
职责链模式通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。
职责链模式使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
Handler:抽象的处理者,定义了一个处理请求的接口,同时含有另外Handler
ConcreteHandlerA, B:具体的处理者,处理它自己负责的请求,可以访问它的后继者 (即下一个处理者),如果可以处理当前请求则处理,否则就将该请求交个后继者去处理,从而形成一个职责链
Request:含有很多属性,表示一个请求
类图
PurchaseRequest类,表示一个请求
- public class PurchaseRequest {
- private int type;//请求类型
- private float price = 0.0f;
- private int id = 0;
-
- public PurchaseRequest(int type, float price, int id) {
- this.type = type;
- this.price = price;
- this.id = id;
- }
-
- public int getType() {
- return type;
- }
-
- public float getPrice() {
- return price;
- }
-
- public int getId() {
- return id;
- }
- }
Approver抽象类,抽象的处理者,定义了一个处理请求的接口,同时含有另外Approver
- public abstract class Approver {
- Approver approver;
- String name;
-
- public Approver(String name) {
- this.name = name;
- }
-
- //下一个处理者
- public void setApprover(Approver approver) {
- this.approver = approver;
- }
-
- //处理审批请求的方法,得到一个请求,处理是子类实现
- public abstract void processRequest(PurchaseRequest purchaseRequest);
- }
DepartmentApprove类,继承Approver抽象类,表示系领导处理
- public class DepartmentApprove extends Approver{
- public DepartmentApprove(String name) {
- super(name);
- }
-
- @Override
- public void processRequest(PurchaseRequest purchaseRequest) {
- if(purchaseRequest.getPrice()<=5000){
- System.out.println("请求编号:"+purchaseRequest.getId()+"被"+this.name+"处理");
- }else {
- approver.processRequest(purchaseRequest);
- }
- }
- }
CollegeApprove类,继承Approver抽象类,表示院领导处理
- public class CollegeApprove extends Approver{
- public CollegeApprove(String name) {
- super(name);
- }
-
- @Override
- public void processRequest(PurchaseRequest purchaseRequest) {
- if(purchaseRequest.getPrice()>=5000&&purchaseRequest.getPrice()<=50000){
- System.out.println("请求编号:"+purchaseRequest.getId()+"被"+this.name+"处理");
- }else {
- approver.processRequest(purchaseRequest);
- }
- }
- }
SchoolApprove类,继承Approver抽象类,表示校领导处理
- public class SchoolApprove extends Approver{
- public SchoolApprove(String name) {
- super(name);
- }
-
- @Override
- public void processRequest(PurchaseRequest purchaseRequest) {
- if(purchaseRequest.getPrice()>=500000){
- System.out.println("请求编号:"+purchaseRequest.getId()+"被"+this.name+"处理");
- }
- }
- }
Client类,模拟学校处理审批过程
- public class Client {
- public static void main(String[] args) {
- PurchaseRequest purchaseRequest1 = new PurchaseRequest(1, 1000, 1);
- PurchaseRequest purchaseRequest2 = new PurchaseRequest(2, 50000, 2);
- PurchaseRequest purchaseRequest3 = new PurchaseRequest(2, 500001, 3);
-
- DepartmentApprove departmentApprove = new DepartmentApprove("系领导");
- CollegeApprove collegeApprove = new CollegeApprove("院领导");
- SchoolApprove schoolApprove = new SchoolApprove("校领导");
- //设置下一级处理人
- departmentApprove.setApprover(collegeApprove);
- collegeApprove.setApprover(schoolApprove);
- //都从系领导开始处理
- departmentApprove.processRequest(purchaseRequest1);
- departmentApprove.processRequest(purchaseRequest2);
- departmentApprove.processRequest(purchaseRequest3);
- }
- }
输出结果
将请求和处理分开,实现解耦,提高系统的灵活性
简化了对象,使对象不需要知道链的结构
性能会受到影响,特别是在链比较长的时候,因此需控制链中最大节点数量,一般通过在Handler中设置一个最大节点数量,在setNext()方法中判断是否已经超过阀值,超过则不允许该链建立,避免出现超长链无意识地破坏系统性能
调试不方便,采用了类似递归的方式,调试时逻辑可能比较复杂
多个对象可以处理同一个请求时,比如:多级请求、请假/加薪等审批流程、Java Web中Tomcat对Encoding的处理、拦截器等
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。