简介
一、定义
- 职责链(Chain of Responsibility)模式:避免将请求发送者与接受者耦合在一起,让多个对象都有机会接受请求,将这些对象连成一条链,并且沿着这条链传递请求,直到有对象处理它为止。职责链模式是一种对象行为型模式。
二、组件
- Handler(抽象处理者):它定义了一个处理请求的接口,一般设计为抽象类,由于不同的具体处理者处理请求的方式不同,因此在其中定义了抽象请求处理方法。因为每一个处理者的下家还是一个处理者,因此在抽象处理者中定义了一个抽象处理者类型的对象(如结构图中的successor),作为其对下家的引用。通过该引用,处理者可以连成一条链。
- ConcreteHandler(具体处理者):它是抽象处理者的子类,可以处理用户请求,在具体处理者类中实现了抽象处理者中定义的抽象请求处理方法,在处理请求之前需要进行判断,看是否有相应的处理权限,如果可以处理请求就处理它,否则将请求转发给后继者;在具体处理者中可以访问链中下一个对象,以便请求的转发。
三、结构图

示例:采购单分级审批
一、请求类
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);
}
}
总结
一、优缺点
1、优点
- 使得一个对象无需知道是其他哪一个对象处理其请求,对象仅需知道该请求会被处理即可,且链式结构由客户端创建 => 降低了系统的耦合度
- 在系统中增加一个新的具体处理者无须修改原有系统源代码,只需要在客户端重新建立链式结构即可 => 符合开闭原则
2、缺点
- 由于一个请求没有一个明确地接受者 => 无法保证它一定会被处理
- 对于较长的职责链 => 系统性能有一定影响且不利于调试
- 如果建立链不当,可能会造成循环调用 => 导致系统进入死循环
二、使用场景
- 有多个对象处理同一个请求且无需关心请求的处理对象时谁以及它是如何处理的 => 比如各种审批流程
- 可以动态地指定一组对象处理请求,客户端可以动态创建职责链来处理请求,还可以改变链中处理者之间的先后次序 => 比如各种流程定制
三、纯与不纯的职责链模式
1、 纯的职责链模式
- 一个纯的职责链模式要求一个具体处理者对象要么承担全部责任,要么将责任推给下家,不允许出现部分处理或者全部处理又向后传递的情况;
- 在纯的职责链模式中,要求一个请求必须被某一个处理者对象所接收,不能又最后请求未被处理的情况
2、 不纯的职责链模式
- 在一个不纯的职责链模式中允许某个请求被一个具体处理者部分处理后再向下传递,或者一个具体处理者处理完某请求后其后继处理者可以继续处理该请求
- 而且一个请求可以最终不被任何处理者对象所接收
参考:java设计模式之职责链模式