3.1设计模式——Chain of Responsibility 责任链模式(行为型)

意图

使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系,将这些对象练成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。

实现

其中

  • Handle定义一个处理请求的接口:(可选)实现后继续。
  • ConcreteHandle处理它所负担的请求;可访问它的后继者;如果有可处理请求,就处理它,否则将该请求转发给后继者。
  • Client向链上的具体处理处理者(ConcreteHandler)对象提交请求。

适用性

Chain of Responsibility模式适用于一下模式:

  • 有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。
  • 想在太明确指定接收者的情况下向多个对象中的一个提交一个请求。
  • 可处理一个请求的对象集合应被动态指定。

代码示例

场景:

假设开发一个邮件处理系统,该系统需要根据邮件的主题和内容进行不同的处理,例如:

  • 如果邮件主题包含 "紧急",则立即发送给相关负责人。
  • 如果邮件内容包含 "投诉",则转发给客服部门处理。
  • 如果邮件内容包含 "广告",则自动标记为垃圾邮件。
  • 如果以上条件都不满足,则将邮件归档。

实现:

可以使用责任链模式来设计这个系统。该模式的核心思想是将多个处理对象链接成一条链,当一个请求到来时,它会沿着链条传递,直到找到合适的处理对象为止。

java 复制代码
// 抽象处理者
abstract class Handler {
    protected Handler nextHandler;

    public void setNextHandler(Handler nextHandler) {
        this.nextHandler = nextHandler;
    }

    public abstract void handleRequest(Email email);
}

// 具体处理者1:紧急邮件处理者
class UrgentHandler extends Handler {
    @Override
    public void handleRequest(Email email) {
        if (email.getSubject().contains("紧急")) {
            System.out.println("紧急邮件处理者处理邮件:" + email.getSubject());
        } else {
            nextHandler.handleRequest(email);
        }
    }
}

// 具体处理者2:投诉邮件处理者
class ComplaintHandler extends Handler {
    @Override
    public void handleRequest(Email email) {
        if (email.getContent().contains("投诉")) {
            System.out.println("投诉邮件处理者处理邮件:" + email.getSubject());
        } else {
            nextHandler.handleRequest(email);
        }
    }
}

// 具体处理者3:广告邮件处理者
class SpamHandler extends Handler {
    @Override
    public void handleRequest(Email email) {
        if (email.getContent().contains("广告")) {
            System.out.println("广告邮件处理者处理邮件:" + email.getSubject());
        } else {
            nextHandler.handleRequest(email);
        }
    }
}

// 具体处理者4:默认邮件处理者
class DefaultHandler extends Handler {
    @Override
    public void handleRequest(Email email) {
        System.out.println("默认邮件处理者处理邮件:" + email.getSubject());
    }
}

// 邮件类
class Email {
    private String subject;
    private String content;

    public Email(String subject, String content) {
        this.subject = subject;
        this.content = content;
    }

    public String getSubject() {
        return subject;
    }

    public String getContent() {
        return content;
    }
}

// 测试类
public class Main {
    public static void main(String[] args) {
        // 创建处理者链
        Handler urgentHandler = new UrgentHandler();
        Handler complaintHandler = new ComplaintHandler();
        Handler spamHandler = new SpamHandler();
        Handler defaultHandler = new DefaultHandler();

        urgentHandler.setNextHandler(complaintHandler);
        complaintHandler.setNextHandler(spamHandler);
        spamHandler.setNextHandler(defaultHandler);

        // 创建邮件
        Email email1 = new Email("紧急:系统故障", "系统出现故障,请尽快处理");
        Email email2 = new Email("投诉:产品质量问题", "产品质量存在问题,要求退货");
        Email email3 = new Email("广告:免费送手机", "免费送手机,数量有限,快来抢购");
        Email email4 = new Email("普通邮件", "这是一封普通邮件");

        // 处理邮件
        urgentHandler.handleRequest(email1);
        urgentHandler.handleRequest(email2);
        urgentHandler.handleRequest(email3);
        urgentHandler.handleRequest(email4);
    }
}

代码设计注释:

  • Handler 抽象类定义了处理请求的接口,并提供了一个 setNextHandler 方法用于链接处理者。
  • 每个具体的处理者类都继承自 Handler 抽象类,并重写 handleRequest 方法来实现自己的处理逻辑。
  • Email 类代表邮件对象,包含邮件的主题和内容。
  • Main 类中创建了处理者链,并创建了不同的邮件对象,然后调用 handleRequest 方法来处理这些邮件。
相关推荐
q***33373 小时前
oracle 12c查看执行过的sql及当前正在执行的sql
java·sql·oracle
在未来等你6 小时前
AI Agent设计模式 Day 19:Feedback-Loop模式:反馈循环与自我优化
设计模式·llm·react·ai agent·plan-and-execute
Y***h1876 小时前
第二章 Spring中的Bean
java·后端·spring
8***29316 小时前
解决 Tomcat 跨域问题 - Tomcat 配置静态文件和 Java Web 服务(Spring MVC Springboot)同时允许跨域
java·前端·spring
CoderYanger6 小时前
优选算法-栈:67.基本计算器Ⅱ
java·开发语言·算法·leetcode·职场和发展·1024程序员节
q***06296 小时前
Tomcat的升级
java·tomcat
多多*7 小时前
Java复习 操作系统原理 计算机网络相关 2025年11月23日
java·开发语言·网络·算法·spring·microsoft·maven
青云交7 小时前
Java 大视界 -- Java 大数据在智能物流无人配送车路径规划与协同调度中的应用
java·spark·路径规划·大数据分析·智能物流·无人配送车·协同调度
d***81727 小时前
解决SpringBoot项目启动错误:找不到或无法加载主类
java·spring boot·后端
ᐇ9597 小时前
Java集合框架深度实战:构建智能教育管理与娱乐系统
java·开发语言·娱乐