一、什么是职责链模式
职责链模式是一种行为型设计模式,它允许将请求沿着处理者的链进行传递,直到有一个处理者能够处理它为止。换句话说,它将请求的发送者和接收者解耦,使得多个对象都有机会处理这个请求,从而避免了将请求直接发送给具体的处理者。
在职责链模式中,多个处理者对象形成一个链,客户端将请求传递给链中的第一个处理者,由第一个处理者决定是自己处理请求,还是将请求传递给下一个处理者,直到请求被处理或者链末尾没有处理者为止。
二、职责链模式的结构
- Handler(处理者):定义处理请求的接口,并且可以访问下一个处理者。
- ConcreteHandler(具体处理者):实现了处理请求的具体逻辑,如果能够处理该请求,则处理它,如果不能处理,则将请求传递给链中的下一个处理者。
- Client(客户端):发起请求并传递给链中的第一个处理者。
三、职责链模式的优点
- 降低耦合性:请求发送者和请求接收者解耦,发送者无需知道具体处理者。
- 灵活性:可以灵活地组织处理者链,可以动态地改变链的结构。
- 简化代码:职责链模式可以避免多重条件语句,使代码更简洁。
四、职责链模式的缺点
- 链过长:如果链太长,可能会导致性能问题。
- 处理不当:如果没有合适的处理者,可能会造成请求得不到处理。
五、案例讲解:客服支持系统
假设我们有一个客服支持系统,客户提交的问题根据其优先级需要经过不同层级的客服人员处理。优先级较低的问题由初级客服处理,优先级较高的问题由技术支持人员处理,如果问题依然没有解决,那么会交给经理来处理。
我们可以使用职责链模式来处理这个场景。以下是完整的代码实现。
六、代码实现
1.问题设计(SupportTicket)
public class SupportTicket {
private String description; // 问题描述
private int priority; // 问题优先级,数值越大表示优先级越高
public SupportTicket(String description, int priority) {
this.description = description;
this.priority = priority;
}
public String getDescription() {
return description;
}
public int getPriority() {
return priority;
}
}
SupportTicket
类表示客户提交的问题,包含问题的描述和优先级。
2.抽象支持处理者(SupportHandler)
public abstract class SupportHandler {
private SupportHandler nextHandler; // 下一个处理者
// 设置下一个处理者
public void setNextHandler(SupportHandler nextHandler){
this.nextHandler = nextHandler;
}
// 获取下一个处理者
public SupportHandler getNextHandler(){
return nextHandler;
}
// 处理请求的方法
public abstract void handleTicket(SupportTicket ticket);
}
SupportHandler
是职责链模式中的抽象处理者,它定义了处理请求的方法 handleTicket
,并且维护了一个指向下一个处理者的引用(nextHandler
)。
3.初级支持处理者(JuniorSupport)
public class JuniorSupport extends SupportHandler{
@Override
public void handleTicket(SupportTicket ticket) {
if(ticket.getPriority() <= 2){
System.out.println("初级客服处理问题:"+ticket.getDescription());
} else if (getNextHandler() != null) {
getNextHandler().handleTicket(ticket); // 传递给下一个处理者
} else {
System.out.println("问题过大,需要汇报给总部处理!!!");
}
}
}
JuniorSupport
是一个具体处理者类,当问题的优先级小于等于 2 时,它会处理该问题。如果问题优先级较高,它会将请求传递给下一个处理者。
4.技术支持处理者(TechSupport)
public class TechSupport extends SupportHandler{
@Override
public void handleTicket(SupportTicket ticket) {
if(ticket.getPriority() <= 4){
System.out.println("技术员处理问题:"+ticket.getDescription());
} else if (getNextHandler() != null) {
getNextHandler().handleTicket(ticket); // 传递给下一个处理者
} else {
System.out.println("问题过大,需要汇报给总部处理!!!");
}
}
}
TechSupport
处理优先级小于等于 4 的问题,其他问题会传递给下一个处理者。
5.经理支持处理者(ManagerSupport)
public class ManagerSupport extends SupportHandler{
@Override
public void handleTicket(SupportTicket ticket) {
if(ticket.getPriority() <= 10){
System.out.println("经理处理问题:"+ticket.getDescription());
} else if (getNextHandler() != null) {
getNextHandler().handleTicket(ticket);
} else {
System.out.println("问题过大,需要汇报给总部处理!!!");
}
}
}
ManagerSupport
处理优先级小于等于 10 的问题,其他问题会传递给下一个处理者,直到链的末尾。
6.测试类(TestChain)
public class TestChain {
public static void main(String[] args) {
// 问题声明
SupportTicket ticket1 = new SupportTicket("线路混乱", 1);
SupportTicket ticket2 = new SupportTicket("服务器异常", 113);
// 处理者声明
SupportHandler handler1 = new JuniorSupport();
SupportHandler handler2 = new TechSupport();
SupportHandler handler3 = new ManagerSupport();
// 处理者链的组装
handler1.setNextHandler(handler2);
handler2.setNextHandler(handler3);
// 问题处理的传递
handler1.handleTicket(ticket1);
handler1.handleTicket(ticket2);
}
}
在 TestChain
中,我们创建了三个处理者(JuniorSupport
、TechSupport
、ManagerSupport
),并将它们串联成一个处理链。当请求传递给第一个处理者时,若它不能处理请求,就将请求交给下一个处理者,直到找到合适的处理者或者到达链的末尾。
7. 总结
职责链模式通过将请求沿着处理者链进行传递,使得每个处理者只关心自己能处理的请求,从而减少了发送者与接收者之间的耦合。职责链模式有助于系统的灵活扩展,因为我们可以在运行时动态地调整处理链结构。通过这种模式,能够实现请求的逐层处理,直到有一个处理者能够处理该请求为止。