设计模式的故事:责任链模式

故事

在一个偏远的小镇上,有一个叫做“责任链咖啡馆”的地方。这个咖啡馆有着独特的经营理念,即通过使用责任链模式来处理客户的订单。

这个咖啡馆的负责人是一位名叫Jack的人,他非常喜欢Java设计模式,并且在经营咖啡馆的时候也喜欢运用这些模式。因此,他决定在咖啡馆的运营中使用责任链模式

在这个咖啡馆中,每个订单都会通过一个处理链来进行处理。这个处理链包含了多个处理节点,每个节点都有自己的处理逻辑。当一个订单到达咖啡馆时,会从链的头部开始处理,直到最后一个节点结束,完成整个订单的处理。

举个例子,比如有一个客人点了一杯咖啡和一块蛋糕。这个订单会首先进入到咖啡处理节点中,进行咖啡的制作。制作完成后,订单会继续流转到下一个节点,即蛋糕处理节点中,进行蛋糕的制作。最后,订单会进入到结算节点中,完成订单的结算。

这个处理链的好处在于,每个节点只需要关注自己的处理逻辑,而不需要关心整个订单的处理过程。这样可以提高代码的可读性和可维护性,并且也方便对处理链进行扩展和修改。

故事讲完了,接下来讲知识点

责任链模式包含以下角色:

  1. 抽象处理者(Handler):定义了一个处理请求的接口,并且包含了一个指向下一个处理者的引用。
  2. 具体处理者(ConcreteHandler):实现了抽象处理者的接口,并且处理它所负责的请求。如果该处理者无法处理请求,那么它会将请求传递给下一个处理者。
  3. ** 客户端(Client)**:创建了一个责任链,并且向该链中的第一个处理者发出请求。

责任链模式通常用于以下场景:

  1. 处理复杂的请求:当一个请求需要被多个对象处理时,可以使用责任链模式来分解该请求,并且使得每个对象都只需要关注自己的处理部分。
  2. 避免请求发送者和接收者之间的耦合关系:通过将请求的发送者和接收者解耦,可以使得系统更加灵活,并且易于维护。
  3. 可以动态地增加或删除处理者:由于责任链中的对象是动态添加或删除的,因此可以根据需要进行动态调整。

示例

为了更好地理解责任链模式,我们可以看一个简单的示例。

假设我们正在开发一个客户服务系统,该系统中需要对客户的投诉进行处理。投诉可以被分为三种类型:一般投诉、严重投诉和紧急投诉。每个投诉都需要被处理,并且需要根据投诉的类型来决定如何处理。如果一个处理者无法处理某个投诉,那么该投诉将被传递给下一个处理者,直到被处理为止。

我们可以使用责任链模式来实现这个功能。首先,我们需要定义一个抽象处理者类,该类包含一个指向下一个处理者的引用和一个处理请求的方法。

public abstract class ComplaintHandler {
    protected ComplaintHandler successor;

    public void setSuccessor(ComplaintHandler successor) {
    this.successor = successor;
}

public abstract void handleComplaint(Complaint complaint);
}

然后,我们可以定义三个具体处理者类,分别用于处理一般投诉、严重投诉和紧急投诉。这三个处理者类都继承自抽象处理者类,并且实现了处理请求的方法。

public class GeneralComplaintHandler extends ComplaintHandler {
    @Override
    public void handleComplaint(Complaint complaint) {
        if (complaint.getType() == ComplaintType.GENERAL) {
            System.out.println("一般投诉已经被处理。");
        } else {
            successor.handleComplaint(complaint);
        }
    }
}

public class SeriousComplaintHandler extends ComplaintHandler {
    @Override
    public void handleComplaint(Complaint complaint) {
        if (complaint.getType() == ComplaintType.SERIOUS) {
            System.out.println("严重投诉已经被处理。");
        } else {
            successor.handleComplaint(complaint);
        }
    }
}

public class EmergencyComplaintHandler extends ComplaintHandler {
    @Override
    public void handleComplaint(Complaint complaint) {
        if (complaint.getType() == ComplaintType.EMERGENCY) {
            System.out.println("紧急投诉已经被处理。");
        } else {
            System.out.println("无法处理该投诉。");
        }
    }
}

最后,我们可以创建一个责任链,并且向该链中的第一个处理者发出请求。

public class ComplaintService {
    private ComplaintHandler complaintHandler;

    public ComplaintService() {
        complaintHandler = new GeneralComplaintHandler();
        ComplaintHandler seriousHandler = new SeriousComplaintHandler();
        ComplaintHandler emergencyHandler = new EmergencyComplaintHandler();

        complaintHandler.setSuccessor(seriousHandler);
        seriousHandler.setSuccessor(emergencyHandler);
    }

    public void handleComplaint(Complaint complaint) {
        complaintHandler.handleComplaint(complaint);
    }
}

使用上述代码,我们就可以根据投诉的类型来决定如何处理该投诉,并且可以动态添加或删除处理者。

Spring中的应用

Spring框架中也使用了责任链模式,其中最常见的应用是拦截器(Interceptor)。拦截器是一种在请求处理过程中,可以拦截请求并进行处理的组件。在Spring框架中,拦截器通常用于实现AOP(面向切面编程)功能。

拦截器通常是以责任链的形式存在的。在Spring框架中,每个拦截器都继承自HandlerInterceptor接口,并且包含了三个方法:preHandle、postHandle和afterCompletion。这三个方法分别在请求处理前、请求处理后和请求处理完成后调用。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容