In object-oriented design, the chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain.
在面向对象的设计来讲,责任链模式是一种组装命令对象和多个处理对象的模式,每个处理对象定义了他能处理的对象的类型以及处理逻辑,否则将会交由之后的处理对象来进行处理。
说白了,实际责任链设计模式就是一种面向对象的if ... else if ... else if ...,只不过能够动态的进行组装。
在看责任链设计模式的时候,发现与Java中现在比较流行的流程化处理(Processor)的思想很相似。本质都是模块的动态组装。不过感觉较大的区别是,责任链模式是为了解决同一个问题来设计的,只不过每个模块能够处理的类型不相同,一个命令对象必定会落到最终的一个模块来处理,在处理过程中入参是并不改变的。而流程化处理则是每个流程处理不同的方面,比如参数校验模块->处理模块->....并且流程化处理主要需要上下文传递信息。
之后有时间专门对流程化的处理进行介绍。现在我们先来看责任链的例子。
责任链类图:
例子,以wiki为例chain of responsibiliy pattern。每个模块只能处理在自己范围内的金额,否则会交由后继来处理。
abstract class PurchasePower {
protected static final double BASE = 500;
protected PurchasePower successor;
abstract protected double getAllowable();
abstract protected String getRole();
public void setSuccessor(PurchasePower successor) {
this.successor = successor;
}
public void processRequest(PurchaseRequest request) {
if (request.getAmount() < this.getAllowable()) {
System.out.println(this.getRole() + " will approve $" + request.getAmount());
} else if (successor != null) {
successor.processRequest(request);
}
}
}
class ManagerPPower extends PurchasePower {
protected double getAllowable() {
return BASE * 10;
}
protected String getRole() {
return "Manager";
}
}
class DirectorPPower extends PurchasePower {
protected double getAllowable() {
return BASE * 20;
}
protected String getRole() {
return "Director";
}
}
class VicePresidentPPower extends PurchasePower {
protected double getAllowable() {
return BASE * 40;
}
protected String getRole() {
return "Vice President";
}
}
class PresidentPPower extends PurchasePower {
protected double getAllowable() {
return BASE * 60;
}
protected String getRole() {
return "President";
}
}
class PurchaseRequest {
private double amount;
private String purpose;
public PurchaseRequest(double amount, String purpose) {
this.amount = amount;
this.purpose = purpose;
}
public double getAmount() {
return this.amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
public String getPurpose() {
return this.purpose;
}
public void setPurpose(String purpose) {
this.purpose = purpose;
}
}
class CheckAuthority {
public static void main(String[] args) {
ManagerPPower manager = new ManagerPPower();
DirectorPPower director = new DirectorPPower();
VicePresidentPPower vp = new VicePresidentPPower();
PresidentPPower president = new PresidentPPower();
manager.setSuccessor(director);
director.setSuccessor(vp);
vp.setSuccessor(president);
// Press Ctrl+C to end.
try {
while (true) {
System.out.println("Enter the amount to check who should approve your expenditure.");
System.out.print(">");
double d = Double.parseDouble(new BufferedReader(new InputStreamReader(System.in)).readLine());
manager.processRequest(new PurchaseRequest(d, "General"));
}
}
catch (Exception exc) {
System.exit(1);
}
}
}