责任链模式可以用一个日常生活中的接力赛来类比。在接力赛中,每个跑步者负责赛道的一段距离,然后将接力棒传递给下一个跑步者,直到最后一个跑步者完成比赛。每个跑步者都有机会跑自己的那一段,但如果他跑不了,他需要将接力棒交给下一个跑步者。
类似地,在责任链模式中,每个处理对象(就像跑步者)都有机会处理请求(就像接力棒)。如果当前处理对象无法处理请求或者认为下一个处理对象更适合处理该请求,它会将请求传递给链中的下一个处理对象。
让我们通过一个具体的生活场景来进一步深入理解责任链模式:
想象一下,你在一家餐厅就餐。你想要点一些特别的菜,但不确定餐厅是否能满足你的需求。于是,你向服务员询问,服务员是请求链上的第一个环节。
-
服务员(第一级处理者):服务员首先听取你的请求,并尝试理解和满足你的需求。如果你的请求是简单的,比如需要额外的餐巾纸,服务员可以直接满足。这就像责任链模式中的处理对象直接处理请求。
-
领班(第二级处理者):如果你的请求是服务员无法满足的,比如你想要为特殊场合装饰餐桌,服务员可能需要询问领班。领班有更多的权限和资源来处理更复杂的请求。
-
厨师(第三级处理者):如果你的请求与食物的特殊制作有关,比如你有特定的食物过敏并需要定制菜单,服务员会将你的需求传递给厨师。厨师是责任链中的另一个环节,他们有能力决定是否能根据你的要求准备食物。
-
餐厅经理(最终处理者):最后,如果你的请求非常特殊,比如你想要在餐厅举办一个惊喜派对并需要特别的安排,这时候可能就需要餐厅经理来决定了。餐厅经理是责任链中的最后一环,他们有最终的决策权。
在整个过程中,每个处理者都有自己的责任和权限范围。他们可以处理在自己能力范围内的请求,如果处理不了,就把请求传递给下一个处理者。责任链模式的好处是,请求的发送者不需要知道谁是最终处理者,他们只需要等待请求得到处理即可。
让我们用一个餐饮服务的例子来演示责任链模式,类似于之前的类比。在这个例子中,当客人提出特殊请求时,服务员、领班、厨师和餐厅经理将根据他们的职责和权限来处理请求。
以下是用Java编写的示例代码:
java
// 请求类
class CustomerRequest {
private String requestType;
private String requestDescription;
public CustomerRequest(String requestType, String requestDescription) {
this.requestType = requestType;
this.requestDescription = requestDescription;
}
public String getRequestType() {
return requestType;
}
public String getRequestDescription() {
return requestDescription;
}
}
// 抽象处理者
abstract class Staff {
protected Staff successor;
public void setSuccessor(Staff successor) {
this.successor = successor;
}
public abstract void handleRequest(CustomerRequest request);
}
// 具体处理者:服务员
class Waiter extends Staff {
@Override
public void handleRequest(CustomerRequest request) {
if ("simple".equals(request.getRequestType())) {
System.out.println("Waiter handled the request: " + request.getRequestDescription());
} else if (successor != null) {
successor.handleRequest(request);
}
}
}
// 具体处理者:领班
class Supervisor extends Staff {
@Override
public void handleRequest(CustomerRequest request) {
if ("complex".equals(request.getRequestType())) {
System.out.println("Supervisor handled the request: " + request.getRequestDescription());
} else if (successor != null) {
successor.handleRequest(request);
}
}
}
// 具体处理者:厨师
class Chef extends Staff {
@Override
public void handleRequest(CustomerRequest request) {
if ("food".equals(request.getRequestType())) {
System.out.println("Chef handled the request: " + request.getRequestDescription());
} else if (successor != null) {
successor.handleRequest(request);
}
}
}
// 具体处理者:餐厅经理
class Manager extends Staff {
@Override
public void handleRequest(CustomerRequest request) {
// 经理可以处理所有类型的请求
System.out.println("Manager handled the request: " + request.getRequestDescription());
}
}
// 客户端
public class RestaurantServiceChain {
public static void main(String[] args) {
// 创建责任链
Staff waiter = new Waiter();
Staff supervisor = new Supervisor();
Staff chef = new Chef();
Staff manager = new Manager();
// 设置责任链的顺序
waiter.setSuccessor(supervisor);
supervisor.setSuccessor(chef);
chef.setSuccessor(manager);
// 创建请求并处理它们
CustomerRequest simpleRequest = new CustomerRequest("simple", "Can I have extra napkins?");
CustomerRequest complexRequest = new CustomerRequest("complex", "Can we get a table with a better view?");
CustomerRequest foodRequest = new CustomerRequest("food", "I have a nut allergy. Can you prepare a nut-free meal?");
CustomerRequest undefinedRequest = new CustomerRequest("undefined", "Can we have a live band tonight?");
waiter.handleRequest(simpleRequest);
waiter.handleRequest(complexRequest);
waiter.handleRequest(foodRequest);
waiter.handleRequest(undefinedRequest);
}
}
在这个例子中,每个处理者(服务员、领班、厨师和经理)依据自己的职责处理请求。如果他们不能处理,就会传递给链中的下一个处理者。这样的设计允许灵活地处理各种类型的客户请求,同时保持处理者之间的解耦。