二十二、责任链模式

目录

      • 1、使用demo演示责任链模式
      • 2、传统方案解决oa系统审批
      • 3、传统方案解决oa系统审批存在的问题
      • 4、职责链模式基本介绍
      • 5、职责链模式原理类图
      • 6、职责链模式解决oa系统采购审批
      • 7、职责链模式的注意事项和细节
      • 8、职责链模式的实际使用场景举例

1、使用demo演示责任链模式

学校oa系统的采购审批项目:需求是
二十二、责任链模式_第1张图片


2、传统方案解决oa系统审批

二十二、责任链模式_第2张图片
在一个类中对教学器材的价格进行判断,然后根据判断调用不同的审批者进行审批


3、传统方案解决oa系统审批存在的问题

  • 客户端这里会使用分支判断来对不用的采购请求进行处理,这样就存在如下问题
    • 如果各个级别的人员审批金额发生变化,客户端也需要相应变化
    • 客户端必须明确知道有多少个审批级别
  • 采购请求和审批人员之间存在强耦合关系,不利于代码的扩展和维护

4、职责链模式基本介绍

职责链模式又称为责任链模式:每个接收者都包含对另一个接收者的引用,如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依次类推


5、职责链模式原理类图

二十二、责任链模式_第3张图片

对职责链模式的说明:

  • Handler:抽象的处理者,定义了一个处理请求的方法,并且聚合了自身
  • ConcreteHandlerA|B:是具体的处理者,处理它自己负责的请求,可以访问它的后继者,如果可以处理当前请求,则处理,否则将该请求交给下个后继者去处理,从而形成一个职责链

6、职责链模式解决oa系统采购审批

1)类图分析
二十二、责任链模式_第4张图片
2)代码实现

// 购买请求
public class PurchaseRequest {

    //
    private int type;

    private float price;

    private int id;

    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;
    }
}

// 审批者抽象类
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);
}


/**
 *  部门主任
 */
public class DepartmentApprover extends Approver {


    public DepartmentApprover(String name) {
        super(name);
    }

    @Override
    public void processRequest(PurchaseRequest purchaseRequest) {
        if (purchaseRequest.getPrice() <= 5000) {
            System.out.println("请求编号 id = " + purchaseRequest.getId() + "被" + this.name + "处理");
        } else {
            // 如果不能处理,则让下一个处理者进行处理
            approver.processRequest(purchaseRequest);
        }
    }
}

/**
 * 系主任
 */
public class CollegeApprover extends Approver {


    public CollegeApprover(String name) {
        super(name);
    }

    @Override
    public void processRequest(PurchaseRequest purchaseRequest) {
        if (purchaseRequest.getPrice() > 5000 && purchaseRequest.getPrice() <= 10000) {
            System.out.println("请求编号 id = " + purchaseRequest.getId() + "被" + this.name + "处理");
        } else {
            // 如果不能处理,则让下一个处理者进行处理
            approver.processRequest(purchaseRequest);
        }
    }
}

/**
 * 副校长
 */
public class ViceSchoolMasterApprover extends Approver {


    public ViceSchoolMasterApprover(String name) {
        super(name);
    }

    @Override
    public void processRequest(PurchaseRequest purchaseRequest) {
        if (purchaseRequest.getPrice() > 10000 && purchaseRequest.getPrice() <= 30000) {
            System.out.println("请求编号 id = " + purchaseRequest.getId() + "被" + this.name + "处理");
        } else {
            // 如果不能处理,则让下一个处理者进行处理
            approver.processRequest(purchaseRequest);
        }
    }
}
/**
 * 校长
 */
public class SchoolMasterApprover extends Approver {


    public SchoolMasterApprover(String name) {
        super(name);
    }

    @Override
    public void processRequest(PurchaseRequest purchaseRequest) {
        if (purchaseRequest.getPrice() > 30000) {
            System.out.println("请求编号 id = " + purchaseRequest.getId() + "被" + this.name + "处理");
        } else {
            // 如果不能处理,则让下一个处理者进行处理
            approver.processRequest(purchaseRequest);
        }
    }
}

public class Client {

    public static void main(String[] args) {

        PurchaseRequest purchaseRequest = new PurchaseRequest(1, 31000, 1);	DepartmentApprover departmentApprover = new DepartmentApprover("张主任");
        CollegeApprover collegeApprover = new CollegeApprover("李院长");
        ViceSchoolMasterApprover viceSchoolMasterApprover = new ViceSchoolMasterApprover("王副校");
        SchoolMasterApprover schoolMasterApprover = new SchoolMasterApprover("佟校长");

        //需要将各个审批级别的下一个设置好 (处理人构成环形: )
        departmentApprover.setApprover(collegeApprover);
        collegeApprover.setApprover(viceSchoolMasterApprover);
        viceSchoolMasterApprover.setApprover(schoolMasterApprover);
        schoolMasterApprover.setApprover(departmentApprover);

        departmentApprover.processRequest(purchaseRequest);

    }
}

二十二、责任链模式_第5张图片


7、职责链模式的注意事项和细节

  • 将请求和处理分开,实现解耦,提高系统的灵活性
  • 性能收到影响,特别是在链比较长的时候。因此需要控制链中最大节点数量,一般通过在Handler中设置一个
    最大节点数量,在setNext方法中判断是否已经超过阈值,超过则不允许建立改节点
  • 由于采取了链的方式,所以调试逻辑比较复杂

8、职责链模式的实际使用场景举例

你可能感兴趣的:(设计模式,责任链模式)