趣解设计模式之《小王看病记》

〇、小故事

小王最近参与了公司一个大项目,工作很忙,经常加班熬夜,满负荷工作了2个月后,项目终于如期上线,并且客户反馈也特别的好。老板很开心,知道大家为这个项目付出了很多,所以给全组同事都放了1个星期的假。

小王在项目期间也经常因为饮食不规范而导致胃疼,最近也越来越严重了。所以他就想趁着这个假期时间去医院检查一下身体

他来到医院的挂号处,首先缴费挂号,挂了一个检查胃部的诊室。

小王按照挂号信息,来到了诊室,医生简单的询问了一下他的病情,然后给他开了几个需要检查的单子

小王带着医生开具的检查单,就在医院的收费处排队等待着缴费

缴费完毕后,小王就按照医生开的检查项目进行了身体检查......

那么从上面小王的一系列看病流程我们可以发现,这是一系列的处理过程,跟链条一样,即:

挂号------>开检查单------>缴费------>检查------>......

那么对于类似这种的业务逻辑,我们就可以使用一种设计模式来处理,即今天要介绍的------责任链模式

一、模式定义

责任链模式Chain of Responsibility Pattern

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

二、模式类图

下面我们再举一个例子,一家公司收到了好多的电子邮件,其中大致分为四类:

CEO处理 】公司粉丝发来的邮件。

法律部门处理诽谤公司产品的邮件。

业务部门处理 】要求业务合作的邮件。

直接丢弃 】其他垃圾邮件。

这里需要CEO先查阅邮件处理,然后再由法务部处理,随后是业务部处理,最后是垃圾邮件执行废弃。根据以上的描述,我们首先需要邮件实体类 Email,和用于区分不同处理方式的邮件类型 EmailType。对于所有处理者,我们首先创建一个抽象的处理器类AbstractProcessor,再创建四个处理器的实现类,分别是CEO处理器 CeoProcessor法务部门处理器 LawProcessor业务部门处理器 BusinessProcessor垃圾邮件处理器 GarbageProcessor。具体类关系如下图所示:

三、模式实现

创建邮件实体类Email.java

java 复制代码
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Email {
    // 邮件类型
    private int type;

    // 邮件内容
    private String content;
}

创建邮件类型枚举类EmailType.java

java 复制代码
public enum EmailType {
    FANS_EMAIL(1, "粉丝邮件"),
    SLANDER_EMAIL(2, "诽谤邮件"),
    COOPERATE_EMAIL(3, "业务合作邮件"),
    GARBAGE_EMAIL(99, "垃圾邮件");

    public int type;

    public String remark;

    EmailType(int type, String remark) {
        this.type = type;
        this.remark = remark;
    }
}

创建抽象处理类AbstractProcessor.java

java 复制代码
public abstract class AbstractProcessor {

    // 责任链中下一个处理节点
    private AbstractProcessor nextProcessor;

    // 返回的处理结果
    private String result;

    public final String handleMessage(List<Email> emails) {
        List<Email> filterEmails =
                emails.stream().filter(email -> email.getType() == this.emailType()).collect(Collectors.toList());
        result = this.execute(filterEmails);
        if (this.nextProcessor == null) {
            return result;
        }
        return this.nextProcessor.handleMessage(emails);
    }

    // 设置责任链的下一个处理器
    public void setNextProcessor(AbstractProcessor processor) {
        this.nextProcessor = processor;
    }

    // 获得当前Processor可以处理的邮件类型
    protected abstract int emailType();

    // 具体处理方法
    protected abstract String execute(List<Email> emails);
}

创建CEO处理类CeoProcessor.java

java 复制代码
public class CeoProcessor extends AbstractProcessor {
    @Override
    protected int emailType() {
        return EmailType.FANS_EMAIL.type; // 处理粉丝来的邮件
    }

    @Override
    protected String execute(List<Email> emails) {
        if (CollectionUtils.isNotEmpty(emails)) {
            System.out.println("-------CEO开始处理邮件-------");
            emails.stream().forEach(email -> 
                                    System.out.println(email.getContent()));
        }
        return "任务执行完毕!";
    }
}

创建法律部门处理类LawProcessor.java

java 复制代码
public class LawProcessor extends AbstractProcessor {

    @Override
    protected int emailType() {
        return EmailType.SLANDER_EMAIL.type; // 处理诽谤类型的邮件
    }

    @Override
    protected String execute(List<Email> emails) {
        if (CollectionUtils.isNotEmpty(emails)) {
            System.out.println("-------法律部门开始处理邮件-------");
            emails.stream().forEach(email -> 
                                    System.out.println(email.getContent()));
        }
        return "任务执行完毕!";
    }
}

创建业务部门处理类BusinessProcessor.java

java 复制代码
public class BusinessProcessor extends AbstractProcessor {

    @Override
    protected int emailType() {
        return EmailType.COOPERATE_EMAIL.type; // 处理合作类型的邮件
    }

    @Override
    protected String execute(List<Email> emails) {
        if (CollectionUtils.isNotEmpty(emails)) {
            System.out.println("-------业务部门开始处理邮件-------");
            emails.stream().forEach(email -> 
                                    System.out.println(email.getContent()));
        }
        return "任务执行完毕!";
    }
}

创建垃圾邮件处理类GarbageProcessor.java

java 复制代码
public class GarbageProcessor extends AbstractProcessor {

    @Override
    protected int emailType() {
        return EmailType.GARBAGE_EMAIL.type; // 处理垃圾类型邮件
    }

    @Override
    protected String execute(List<Email> emails) {
        if (CollectionUtils.isNotEmpty(emails)) {
            System.out.println("-------垃圾开始处理邮件-------");
            emails.stream().forEach(email -> 
                                    System.out.println(email.getContent()));
        }
        return "任务执行完毕!";
    }
}

创建责任链模式测试类ChainTest.java

java 复制代码
public class ChainTest {
    // 初始化待处理邮件
    private static List<Email> emails = Lists.newArrayList(
        	new Email(EmailType.FANS_EMAIL.type, "我是粉丝A"),
            new Email(EmailType.COOPERATE_EMAIL.type, "我要找你们合作"),
            new Email(EmailType.GARBAGE_EMAIL.type, "我是垃圾邮件"),
            new Email(EmailType.FANS_EMAIL.type, "我是粉丝B"));

    public static void main(String[] args) {
        // 初始化处理类
        AbstractProcessor ceoProcessor = new CeoProcessor();
        AbstractProcessor lawProcessor = new LawProcessor();
        AbstractProcessor businessProcessor = new BusinessProcessor();
        AbstractProcessor garbageProcessor = new GarbageProcessor();

        // 设置责任链条
        ceoProcessor.setNextProcessor(lawProcessor);
        lawProcessor.setNextProcessor(businessProcessor);
        businessProcessor.setNextProcessor(garbageProcessor);

        // 开始处理邮件
        ceoProcessor.handleMessage(emails);
    }
}

执行后的结果

java 复制代码
-------CEO开始处理邮件-------
我是粉丝A
我是粉丝B
-------业务部门开始处理邮件-------
我要找你们合作
-------垃圾开始处理邮件-------
我是垃圾邮件

Process finished with exit code 0

今天的文章内容就这些了:

写作不易,笔者几个小时甚至数天完成的一篇文章,只愿换来您几秒钟的 点赞 & 分享

更多技术干货,欢迎大家关注公众号"爪哇缪斯" ~ \(^o^)/ ~ 「干货分享,每天更新」

相关推荐
许苑向上5 分钟前
Dubbo集成SpringBoot实现远程服务调用
spring boot·后端·dubbo
闲人一枚(学习中)35 分钟前
设计模式-创建型-抽象工厂模式
设计模式·抽象工厂模式
郑祎亦1 小时前
Spring Boot 项目 myblog 整理
spring boot·后端·java-ee·maven·mybatis
本当迷ya1 小时前
💖2025年不会Stream流被同事排挤了┭┮﹏┭┮(强烈建议实操)
后端·程序员
陪学1 小时前
百度遭初创企业指控抄袭,维权还是碰瓷?
人工智能·百度·面试·职场和发展·产品运营
计算机毕设指导62 小时前
基于 SpringBoot 的作业管理系统【附源码】
java·vue.js·spring boot·后端·mysql·spring·intellij-idea
paopaokaka_luck2 小时前
[371]基于springboot的高校实习管理系统
java·spring boot·后端
小白不太白9503 小时前
设计模式之 观察者模式
观察者模式·设计模式
大数据编程之光3 小时前
Flink Standalone集群模式安装部署全攻略
java·大数据·开发语言·面试·flink
捂月3 小时前
Spring Boot 深度解析:快速构建高效、现代化的 Web 应用程序
前端·spring boot·后端