设计模式之责任链模式

责任链模式☆☆

定义:避免将一个请求的发送者和接受者耦合在一起,让多个对象都有机会处理请求,将接受请求的对象链接成一条链,并且沿着这条链传递请求,知道有一个对象能够处理它为止、

1.代码案例

采购人员申请金额进行多级审批,

代码演示:

采购类

package com.company.Demo;
​
public class PurchaseRequest {
​
    public PurchaseRequest(double amount, int number, String purpose) {
        this.amount = amount;
        this.number = number;
        this.purpose = purpose;
    }
​
    //采购金额
    private double amount;
​
    // 采购单编号
    private int number;
​
    // 采购目的
    private String  purpose;
​
    public double getAmount() {
        return amount;
    }
​
    public void setAmount(double amount) {
        this.amount = amount;
    }
​
    public int getNumber() {
        return number;
    }
​
    public void setNumber(int number) {
        this.number = number;
    }
​
    public String getPurpose() {
        return purpose;
    }
​
    public void setPurpose(String purpose) {
        this.purpose = purpose;
    }
}

审批者类:

package com.company.Demo;
public abstract class Approver {
​
    // 定义后继对象
    protected Approver successor;
​
    //审批者姓名
    protected String name;
​
    public Approver(String name){
        this.name=name;
    }
​
    //设置后继者
    public void setSuccessor(Approver successor) {
        this.successor = successor;
    }
​
    public abstract  void processRequest(PurchaseRequest request);
​
}

主任类:

package com.company.Demo;
public class Director extends Approver {
    public Director(String name) {
        super(name);
    }
​
    @Override
    public void processRequest(PurchaseRequest request) {
        if (request.getAmount()<50000){
            System.out.println("主任:"+this.name+",审批采购单:"+request.getNumber()+"" +
                    ",金额:"+request.getAmount()+"元,采购目的"+request.getPurpose());
        }else {
            // 请求转发
            this.successor.processRequest(request);
        }
    }
}

副董事长类:

package com.company.Demo;
public class VicePresident extends Approver {
    
    public VicePresident(String name) {
        super(name);
    }
    
    @Override
    public void processRequest(PurchaseRequest request) {
        if (request.getAmount()<100000){
            System.out.println("副董事长:"+this.name+",审批采购单:"+request.getNumber()+"" +",金额:"+request.getAmount()+"元,采购目的"+request.getPurpose());
        }else {
            // 请求转发
            this.successor.processRequest(request);
        }
    }
}

董事长类:

package com.company.Demo;
public class President extends Approver {
    
    public President(String name) {
        super(name);
    }
​
    @Override
    public void processRequest(PurchaseRequest request) {
        if (request.getAmount()<500000){
            System.out.println("董事长:"+this.name+",审批采购单:"+request.getNumber()+"" +
                    ",金额:"+request.getAmount()+"元,采购目的"+request.getPurpose());
        }else {
            // 请求转发
            this.successor.processRequest(request);
        }
    }
}

董事会类:

package com.company.Demo;
public class Congress extends Approver {
    
    public Congress(String name) {
        super(name);
    }
​
    @Override
    public void processRequest(PurchaseRequest request) {
           System.out.println("召开董事会审批采购单:"+request.getNumber()+"" +
                    ",金额:"+request.getAmount()+"元,采购目的"+request.getPurpose());
​
    }
}

测试类:

package com.company.Demo;
​
public class Main {
​
    public static void main(String[] args) {
        Approver zhang,li,wang,congress;
        zhang=new Director("张三");
        li=new VicePresident("李四");
        wang=new President("王五");
        congress=new Congress("董事长");
​
        //创建责任链
        zhang.setSuccessor(li);
        li.setSuccessor(wang);
        wang.setSuccessor(congress);
​
        //创建采购单
        PurchaseRequest request=new PurchaseRequest(45000,10001,"购买倚天剑");
        zhang.processRequest(request);
​
        PurchaseRequest request1=new PurchaseRequest(60000,10002,"购买《葵花宝典》");
        zhang.processRequest(request1);
        
        PurchaseRequest request2=new PurchaseRequest(160000,10003,"购买《金刚经》");
        zhang.processRequest(request2);
        
        PurchaseRequest request3=new PurchaseRequest(800000,10004,"购买桃花岛");
        zhang.processRequest(request3);
        
    }
}

测试结果:

主任:张三,审批采购单:10001,金额:45000.0元,采购目的购买倚天剑

副董事长:李四,审批采购单:10002,金额:60000.0元,采购目的购买《葵花宝典》

董事长:王五,审批采购单:10003,金额:160000.0元,采购目的购买《金刚经》

召开董事会审批采购单:10004,金额:800000.0元,采购目的购买桃花岛

如果需要在系统中新加一个处理者,只需要新加一个类并且继承Approver ,新加一个一段代码就可以。符合开闭原则,对拓展开放,修改关闭。

2.纯与不纯的责任链模式

1.纯的责任链模式:

要求一个具体处理者对象只能在两个行为中选择一个,要么承担全部责任,要么把责任向下推,不存在承担部分责任或者全部承担之后,又向下传递情况。(java 异常处理机制 Exception Handlers)

2.不纯的责任链模模式:

一个具体处理者对象在部分处理之后在向下传递。

3.责任链的优点

1.请求者和接收者都实现了解耦合,请求者不需要知道具体是哪个一个接收者处理了哪一个请求。

2.请求者对象只需要维护一个后继者的引用(单向链表数据结构),而不再需要对它所有的候选处理者的引用,可以简化对象之间的相互连接。

3.对系统需要新增加一个具体的处理类的时候,不需要修改原来的代码,需要新加一个新的处理类,在客户端重新创建链就可以,符合开闭原则。

4.责任链的缺点

1.由于请求没有一个明确的处理者,那么就不能保证它一定会被处理,请求可能到了最后结束也不会被处理,请求可能会被置之不理。

2.如果对于责任链太长的话,系统性能将会受到一定量的影响,而且在进行代码调试的时候不太方便。

3.如果创建链不当的话,可能会造成死循环。

5.责任链的适用情况

1.有多个多想处理同一个请求,具体哪个对象处理该请求待运行时刻在确定,客户端只需将请求提交到链上,而无需关心请求的处理对象是谁以及它是如果处理的。

2.在不明确指定接受者的情况下向多个对象中的一个,提交一个请求。

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值