尚硅谷设计模式笔记-职责链模式

Table of Contents generated with DocToc

笔记来源:尚硅谷设计模式

一、需求

学校OA系统的采购审批项目:需求是

  1. 采购员采购教学器材
  2. 如果金额小于等于5000,由教学主任审批
  3. 如果金额小于等于10000,由院长审批
  4. 如果金额小于等于30000,由副校长审批
  5. 如果金额超过30000以上,有校长审批

二、传统的设计方案

传统方式是:接收到一个采购请求后,根据采购金额【if-else】来调用对应的Approver (审批人)完成审批。

问题:

  • 当审批金额发生了变化。那么则要更改if-else的代码,如果条件很复杂,修改起来很困难
  • 客户端必须明确的知道有多少个审批级别,并且对应的金额

Client和aprrover有强耦合关系


三、职责链模式

职责链模式(Chain of Responsibility Pattern),又叫责任链模式,为请求创建了一个接收者对象的链(简单示意图)。 这种模式对请求的发送者和接收者进行解耦。

我们将处理请求发送给教务主任,如果可以处理就处理,如果不能处理就交给下一个角色(院长),如果院长可以处理就处理,如果不能处理就交给下一个角色(副校长),直到校长。

首先先写好请求类:

public class PurchaseRequest {
    private double price=0.0f;//金额
    private int id;

    public PurchaseRequest(double price, int id) {
        this.price = price;
        this.id = id;
    }

/*get set省略*/
}

然后创建虚拟的解决类(相当于处理者):

public abstract class Handler {
    Handler successor;//保存下一个处理者
    String name;

    public Handler(String name) {
        this.name = name;
    }
    //处理审批请求的方法,得到一个请求,处理是子类完成,因此该方法做成抽象
    public abstract void processRequest(PurchaseRequest request) throws Exception;

    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }
}

然后用子类继承,并实现处理方法(此处以系主任为例):

//系主任
public class DepartmentApprover extends Handler{
    public DepartmentApprover(String name) {
        super(name);
    }

    @Override
    public void processRequest(PurchaseRequest request) throws Exception {
        if(request.getPrice() <= 5000)
            System.out.println("请求编号为"+request.getId()+"被"+this.name+"处理");
        
        //如果不满足条件,则丢给下一个处理者
        else
            successor.processRequest(request);

    }
}

在Client中生成责任链,并发送请求【切记责任链要设计成环状,万一有个1000元的需求从中间责任人(比如副校长)开始处理,也能够传递到系主任】

public class Client {
    public static void main(String[] args) throws Exception {
        PurchaseRequest request = new PurchaseRequest(3500,1);
        Handler departmentApprover = new DepartmentApprover("系主任");
        Handler collegeApprover = new CollegeApprover("院长");
        Handler viceSchoolApprover = new ViceSchoolApprover("副校长");
        Handler schoolApprover = new SchoolApprover("校长");

        //设置责任链(处理人构成环状)
        schoolApprover.setSuccessor(departmentApprover);
        viceSchoolApprover.setSuccessor(schoolApprover);
        collegeApprover.setSuccessor(viceSchoolApprover);
        departmentApprover.setSuccessor(collegeApprover);


        departmentApprover.processRequest(request);
    }
}

输出为:

请求编号为1被系主任处理

整个实例类图为:

posted @ 2020-07-18 11:03  衍射  阅读(232)  评论(0编辑  收藏  举报