责任链模式☆☆
定义:避免将一个请求的发送者和接受者耦合在一起,让多个对象都有机会处理请求,将接受请求的对象链接成一条链,并且沿着这条链传递请求,知道有一个对象能够处理它为止、
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.在不明确指定接受者的情况下向多个对象中的一个,提交一个请求。