责任链模式简介
责任链模式定义
责任链模式是一种行为设计模式,它的本质在于解耦请求与处理,让请求在处理链中能进行传递与处理。在责任链模式中,多个对象依次处理同一个请求,每个对象都包含对下一个对象的引用。当一个对象处理完请求后,会将请求传递给下一个对象,直到所有对象都处理完毕。这样可以动态地决定请求的处理顺序,并且可以灵活地添加、移除或修改处理对象,而不影响客户端代码。责任链模式的关键在于,每个处理者都知道它的下一个处理者是谁,并且可以在必要时将请求传递给下一个处理者。责任链模式常用于需要按顺序处理请求、避免请求发送者和接收者直接耦合、以及动态指定处理对象的场景。
责任链模式包含以下角色:
- 抽象处理者(Handler):定义一个处理请求的接口,通常包含一个指向下一个处理者的引用。它的作用是提供一个统一的处理方法声明,以便在不同的具体处理者之间传递请求。还声明了由于某个条件的约束,责任链的当前处理者不能处理该请求,因此必须将请求传递给下一个处理者。
- 具体处理者(Concrete Handler):实现抽象处理者接口,并具体判断是否能够处理接收到的请求。如果能够处理,它会进行相应的处理操作;如果不能处理,它则将请求传递给链上的下一个处理者。
- 客户端(Client):创建并提交请求对象,构建责任链,并将请求发送到责任链的第一个处理者。客户类不关心请求的具体处理细节和传递过程,它只负责启动请求的处理流程。
责任链模式优缺点:
优点:
- 解耦性:责任链模式将请求的发送者和接收者解耦,使得请求发送者无需知道请求的具体处理者,增强了系统的灵活性。
- 可扩展性:可以动态地添加、移除或修改处理者,而不需要修改客户端代码,方便对系统进行扩展和维护,且满足开闭原则。
- 提高了系统的灵活性:可以根据请求的内容动态地决定传递给哪个处理者,或者按照一定的顺序依次传递。
- 简化对象:每个具体处理者只需关注自己的处理逻辑,以及如何将请求传递给下一个处理者,处理者之间是相互独立的,从而使得对象职责更加清晰,易于管理和维护。
缺点:
- 请求处理不确定性:由于责任链是依次传递请求的,如果链中的某个处理者没有正确处理请求,也没有将其传递给下一个处理者,那么该请求可能会被忽略。
- 性能影响:因为请求是依次传递的,所以链中的处理者数量越多,处理请求的时间就可能越长。特别是在链很长的情况下,性能问题会更加突出。
- 调试困难:责任链模式中请求的处理流程是动态的,可能会增加调试的难度,特别是责任链较长时,需要仔细跟踪请求的处理路径。
- 设计较复杂:在构建责任链时,需要确保每个处理者都知道其下一个处理者是谁,这增加了设计的复杂性。
使用场景
- 多个对象可以处理同一个请求:当一个请求可以被多个对象处理时,可以使用责任链模式将这些对象组织成一个链,每个对象都有机会处理该请求。
- 解耦请求的发送者和接收者:当客户端不需要知道请求的具体处理细节,只需要将请求发送到责任链上即可时,可以使用责任链模式来降低客户端与处理者的耦合度。
- 动态组织链:当需要根据运行时条件动态地添加或删除处理者时,责任链模式提供了一种灵活的方式来组织处理者。
- 扩展性要求较高:当系统需要支持多种不同的处理方式,并且希望能够方便地添加新的处理方式时,责任链模式可以帮助实现这种可扩展性。
- 需要对请求进行分阶段处理:当一个请求需要经过多个阶段进行处理时,可以使用责任链模式将每个阶段的责任分配给不同的处理者。
- 避免请求被单个对象阻塞:当一个请求的处理时间较长,不希望阻塞整个系统时,可以将请求的处理分散到多个对象中,使用责任链模式来实现异步处理。
以下举一个责任链模式的例子:
下面通过一个简单的例子来演示。
下面以公司员工请假审批流程为例。我们假设有组长,主管和老板。如果一位员工请假,需要根据请假日期,需要经过这三个人审批,但请假天数的不同就需要不同的审批者。
创建抽象处理者对象(Handler)
java
public abstract class Approver {
Approver next;
//设置下一个审批者
public void setNext(Approver next) {
this.next = next;
}
//审批请求
public abstract void approve(Integer request);
}
创建三个具体处理者(Concrete Handler),分别对应组长,主管和老板
java
public class Leader extends Approver {
@Override
public void approve(Integer request) {
if (request <= 1) {
System.out.println("该员工请假" + request + "天,组长可以审批请假");
} else {
if (next != null) {
System.out.println("请假天数过多,组长审批不了,交由上级领导审批");
next.approve(request);
}
}
}
}
java
public class Supervisor extends Approver {
@Override
public void approve(Integer request) {
if (request <= 3) {
System.out.println("该员工请假" + request + "天,主管可以审批请假");
} else {
if (next != null) {
System.out.println("请假天数过多,主管审批不了,交由上级领导审批");
next.approve(request);
}
}
}
}
java
public class Boss extends Approver {
@Override
public void approve(Integer request) {
if (request > 3) {
System.out.println("该员工请假" + request + "天,老板可以审批请假");
} else {
if (next != null) {
System.out.println("请假天数过多,老板审批不了,交由上级领导审批");
next.approve(request);
}
}
}
}
创建客户端(Client)
java
public class Client {
public static void main(String[] args) {
Approver leader = new Leader();
Approver supervisor = new Supervisor();
Approver boss = new Boss();
//组织责任链
leader.setNext(supervisor);
supervisor.setNext(boss);
//发起请求
leader.approve(5);
}
}
输出结果如下所示:
java
请假天数过多,组长审批不了,交由上级领导审批
请假天数过多,主管审批不了,交由上级领导审批
该员工请假5天,老板可以审批请假
在上述例子中,每个审批者对应一个Approver对象,组长、主管和老板分别继承自Approver类。每个Approver对象都有一个next属性,代表下一个审批者,这样就形成了一个责任链。在处理请求的时候,如果当前审批者可以处理请求,就处理请求;否则将请求传递给下一个审批者处理。
可以看到,在这个例子中,如果请假天数小于等于1天,组长就处理请求;如果请假天数小于等于3天,主管就处理请求;如果请假天数大于3天,老板就处理请求。如果当前审批者无法处理请求,就将请求传递给下一个审批者处理,直到所有审批者都处理完成。
总而言之:
责任链模式是一种行为型设计模式,它通过将请求的发送者和接收者解耦,允许多个对象有机会处理请求,从而提供了更大的灵活性和可扩展性。
在责任链模式中,请求沿着一个链传递,直到有一个对象处理它为止。这种模式定义了一个处理请求的接口,通常包含一个处理请求的方法和一个指向下一个处理者的引用。具体处理者实现这个接口,并定义了对请求的处理方式。客户端只需将请求发送到责任链上,无需关心请求的具体处理细节和传递过程。
责任链模式的优点是增加了系统的灵活性,允许动态组织链,支持多个对象处理请求,简化了对象的结构和职责。缺点是可能导致性能问题,调试困难,可能导致循环调用,且不保证请求一定会被处理。
责任链模式适用于多个对象可以处理同一个请求、解耦请求的发送者和接收者、动态组织链、扩展性要求较高、需要对请求进行分阶段处理以及避免请求被单个对象阻塞的场景。
总的来说,责任链模式提供了一种灵活的方式来处理请求,允许多个对象共同处理一个请求,同时保持系统的灵活性和可扩展性。但在使用时需要注意其潜在的性能问题和调试难度。
以上代码下载请点击该链接:https://github.com/Yarrow052/Java-package.git