设计模式完结(13)--职责链模式-- 请求的链式处理
请求的链式处理:
****多个对象都可以处理同一个请求, 每个处理者维护一个下家, 客户端建立链。
链的创建过程由客户端负责
职责链模式定义如下: 职责链模式(Chain of Responsibility Pattern):避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。
abstract class Handler { //维持对下家的引用 protected Handler successor; public void setSuccessor(Handler successor) { this.successor=successor; } public abstract void handleRequest(String request); } class ConcreteHandler extends Handler { public void handleRequest(String request) { if (请求满足条件) { //处理请求 } else { this.successor.handleRequest(request); //转发请求 } } }
//采购单:请求类 class PurchaseRequest { private double amount; //采购金额 private int number; //采购单编号 private String purpose; //采购目的 public PurchaseRequest(double amount, int number, String purpose) { this.amount = amount; this.number = number; this.purpose = purpose; } public void setAmount(double amount) { this.amount = amount; } public double getAmount() { return this.amount; } public void setNumber(int number) { this.number = number; } public int getNumber() { return this.number; } public void setPurpose(String purpose) { this.purpose = purpose; } public String getPurpose() { return this.purpose; } } //审批者类:抽象处理者 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); } //主任类:具体处理者 class Director extends Approver { public Director(String name) { super(name); } //具体请求处理方法 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); //转发请求 } } } //副董事长类:具体处理者 class VicePresident extends Approver { public VicePresident(String name) { super(name); } //具体请求处理方法 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); //转发请求 } } } //董事长类:具体处理者 class President extends Approver { public President(String name) { super(name); } //具体请求处理方法 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); //转发请求 } } } //董事会类:具体处理者 class Congress extends Approver { public Congress(String name) { super(name); } //具体请求处理方法 public void processRequest(PurchaseRequest request) { System.out.println("召开董事会审批采购单:" + request.getNumber() + ",金额:" + request.getAmount() + "元,采购目的:" + request.getPurpose() + "。"); //处理请求 } } class Client { public static void main(String[] args) { Approver wjzhang,gyang,jguo,meeting; wjzhang = new Director("张无忌"); gyang = new VicePresident("杨过"); jguo = new President("郭靖"); meeting = new Congress("董事会"); //创建职责链 wjzhang.setSuccessor(gyang); gyang.setSuccessor(jguo); jguo.setSuccessor(meeting); //创建采购单 PurchaseRequest pr1 = new PurchaseRequest(45000,10001,"购买倚天剑"); wjzhang.processRequest(pr1); PurchaseRequest pr2 = new PurchaseRequest(60000,10002,"购买《葵花宝典》"); wjzhang.processRequest(pr2); PurchaseRequest pr3 = new PurchaseRequest(160000,10003,"购买《金刚经》"); wjzhang.processRequest(pr3); PurchaseRequest pr4 = new PurchaseRequest(800000,10004,"购买桃花岛"); wjzhang.processRequest(pr4); } } 编译并运行程序,输出结果如下: 主任张无忌审批采购单:10001,金额:45000.0元,采购目的:购买倚天剑。 副董事长杨过审批采购单:10002,金额:60000.0元,采购目的:购买《葵花宝典》。 董事长郭靖审批采购单:10003,金额:160000.0元,采购目的:购买《金刚经》。 召开董事会审批采购单:10004,金额:800000.0元,采购目的:购买桃花岛。
由于链的创建过程由客户端负责,因此增加新的具体处理者类对原有类库无任何影响,无须修改已有类的源代码,符合“开闭原则”。
纯的职责链:
要么承担全部责任,要么将责任推给下家;
要求一个请求必须被某一个处理者对象所接收;
不纯的职责链模式:
在一个不纯的职责链模式中允许某个请求被一个具体处理者部分处理后再向下传递,或者一个具体处理者处理完某请求后其后继处理者可以继续处理该请求;
一个请求可以最终不被任何处理者对象所接收。
3.适用场景
(1) 有多个对象可以处理同一个请求,具体哪个对象处理该请求待运行时刻再确定,客户端只需将请求提交到链上,而无须关心请求的处理对象是谁以及它是如何处理的。
(2) 在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
(3) 可动态指定一组对象处理请求,客户端可以动态创建职责链来处理请求,还可以改变链中处理者之间的先后次序。