java责任链模式审批请假_Java使用责任链模式处理学生请假问题详解

本文实例讲述了Java使用责任链模式处理学生请假问题。分享给大家供大家参考,具体如下:

一. 模式定义

在责任链模式中,很多对象由每一个对象对其下家的引用而连接起来,形成一条链。客户端应用请求在这个链上进行传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪个对象最终处理这个请求,这使系统可以在不影响客户端的情况下动态地重新组织链和分配责任。

(1)抽象处理者角色:定义出一个处理请求的接口。如果需要,接口可以定义出一个方法,以设定和返回下家的引用。这个角色通常由一个Java抽象类或Java接口实现。

(2)具体处理角色:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。

二. 模式举例

1 模式分析

我们借用学生请假来说明这一模式

6e7a9b7ba40337ac499d4ebdb659c42f.png

2 责任链模式静态类图

e6e39f89919d246f7b5536d0bedb2e9c.png

3 代码示例

3.1学生接口一IStudent

package com.demo.chain.message;

/**

* 学生接口

*

* @author

*

*/

public interface IStudent {

/**

* 获得学生病情状态

*

* 0:小事(班长就可以处理)

*

* 1:班长处理不了 老师能处理的事

*

* 2:老师处理不了 校长能处理的事

*

*

*/

public int getState();

/**

* 获得学生请假消息

*

* @return

*/

public String getRequestMessage();

}

3.2学生实现一Student

package com.demo.chain.message;

/**

* 学生实现类

*

* @author

*

*/

public class Student implements IStudent {

// 病情的大小状态

private int state = -1;

// 请假消息

private final String message;

public Student(int state, String message) {

this.state = state;

this.message = message;

}

/**

* 获得学生请假状态

*

* 0:小事(班长就可以处理)

*

* 1:班长处理不了 老师能处理的事

*

* 2:老师处理不了 校长能处理的事

*

*

*/

public int getState() {

return this.state;

}

/**

* 获得学生请假消息

*

* @return

*/

public String getRequestMessage() {

return this.message;

}

}

3.3抽象处理接口一IHandler

package com.demo.chain.handle;

import com.demo.chain.message.IStudent;

/**

* 抽象处理者接口

*

* @author

*

*/

public interface IHandler {

// 处理请求

public void handleRequest(IStudent student);

// 设置下一个处理者

public void setHandler(IHandler handler);

}

3.4抽象处理者一AbstractHandler

package com.demo.chain.handle;

import com.demo.chain.message.IStudent;

/**

* 抽象处理者

*

* @author

*

*/

public abstract class AbstractHandler implements IHandler {

// 下一个处理者

private IHandler handler;

// 请假级别

private int state = -1;

// 构造方法 设置级别

public AbstractHandler(int state) {

this.state = state;

}

// 处理请求 交由子类负责进行具体的处理

public abstract void process(IStudent student);

// 处理请求

public void handleRequest(IStudent student) {

// 如果学生对象存在

if (student != null) {

if (this.state == student.getState()) {

// 如果请假级别和当前一致 则当前对象进行处理

this.process(student);

} else {

if (this.handler != null) {

System.out.println("请求上级领导批复!");

// 如果当前对象处理不了 则交给下一个处理者进行处理

this.handler.handleRequest(student);

}

}

}

}

// 设置下一个处理者

public void setHandler(IHandler handler) {

this.handler = handler;

}

}

3.5班长一SquadLeaderHandler

package com.demo.chain.handle;

import com.demo.chain.message.IStudent;

/**

* 抽象处理者

*

* @author

*

*/

public abstract class AbstractHandler implements IHandler {

// 下一个处理者

private IHandler handler;

// 请假级别

private int state = -1;

// 构造方法 设置级别

public AbstractHandler(int state) {

this.state = state;

}

// 处理请求 交由子类负责进行具体的处理

public abstract void process(IStudent student);

// 处理请求

public void handleRequest(IStudent student) {

// 如果学生对象存在

if (student != null) {

if (this.state == student.getState()) {

// 如果请假级别和当前一致 则当前对象进行处理

this.process(student);

} else {

if (this.handler != null) {

System.out.println("请求上级领导批复!");

// 如果当前对象处理不了 则交给下一个处理者进行处理

this.handler.handleRequest(student);

}

}

}

}

// 设置下一个处理者

public void setHandler(IHandler handler) {

this.handler = handler;

}

}

3.6老师一TeacherHandler

package com.demo.chain.impl;

import com.demo.chain.handle.AbstractHandler;

import com.demo.chain.message.IStudent;

/**

* 老师处理者

*

* @author

*

*/

public class TeacherHandler extends AbstractHandler {

public TeacherHandler() {

super(1);

}

// 子类具体处理请求

@Override

public void process(IStudent student) {

System.out.println("老师 批复:" + student.getRequestMessage());

}

}

3.7校长一SchoolMasterHandler

package com.demo.chain.impl;

import com.demo.chain.handle.AbstractHandler;

import com.demo.chain.message.IStudent;

/**

* 校长处理者

*

* @author

*

*/

public class SchoolMasterHandler extends AbstractHandler {

public SchoolMasterHandler() {

super(2);

}

// 子类具体处理请求

@Override

public void process(IStudent student) {

System.out.println("校长 批复:" + student.getRequestMessage());

}

}

3.8外观类一ProcessHandler

package com.demo.chain.process;

import com.demo.chain.handle.IHandler;

import com.demo.chain.impl.SchoolMasterHandler;

import com.demo.chain.impl.SquadLeaderHandler;

import com.demo.chain.impl.TeacherHandler;

import com.demo.chain.message.IStudent;

/**

* 设置责任链关联

*

* @author

*

*/

public class ProcessHandler {

// 班长处理者

private final IHandler sqmshandler;

// 老师处理者

private final IHandler techhandler;

// 校长处理者

private final IHandler scmshandler;

// 单例模式

private static ProcessHandler processHandler = new ProcessHandler();

/**

* 构造方法建立请假处理责任链

*/

private ProcessHandler() {

// 创建处理对象

// 班长

this.sqmshandler = new SquadLeaderHandler();

// 老师

this.techhandler = new TeacherHandler();

// 校长

this.scmshandler = new SchoolMasterHandler();

/**

* 建立责任链

*/

// 设置班长的下一个处理者:老师

this.sqmshandler.setHandler(this.techhandler);

// 设置老师的下一个处理者:校长

this.techhandler.setHandler(this.scmshandler);

}

/**

* 获得单例对象实例

*

* @return

*/

public static ProcessHandler getInstance() {

return processHandler;

}

/**

* 发送请假请求

*

* @param message

*/

public void sendMessage(IStudent student) {

// 发送给第一个处理者:班长 处理

this.sqmshandler.handleRequest(student);

}

}

3.9客户端一Client

package com.demo;

import java.util.Random;

import com.demo.chain.message.IStudent;

import com.demo.chain.message.Student;

import com.demo.chain.process.ProcessHandler;

/**

* 主应用程序

*

* @author

*

*/

public class Client {

/**

* @param args

*/

public static void main(String[] args) {

// 获得外观对象

ProcessHandler processHandler = ProcessHandler.getInstance();

// 创建随机数对象 用来随机产生学生对象

Random random = new Random();

for (int i = 0; i < 3; i++) {

// 获得随机数

int radom = random.nextInt(3);

IStudent student = new Student(radom, "学生" + i + "生病了,要请假!");

System.out.println("#################################");

// 处理消息

processHandler.sendMessage(student);

System.out.println("#################################\n");

}

}

}

4 运行结果

#################################

请求上级领导批复!

请求上级领导批复!

校长 批复:学生0生病了,要请假!

#################################

#################################

请求上级领导批复!

请求上级领导批复!

校长 批复:学生1生病了,要请假!

#################################

#################################

班长 批复:学生2生病了,要请假!

#################################

三. 该模式设计原则

1"开-闭"原则

2单一职责原则

四. 使用场合

(1)有多个对象处理同一请求,具体由哪一个来处理还不确定,只有在运行时才确定哪个对象处理的情况。

(2)消息具有多个接收者,而接收对象又是不明确的情况。只需要向其中的一个对象发出消息,由其内部具体处理。

(3)同一消息的多个处理对象可能会动态增加或减少,需要动态地指定的情况。

五. 责任链模式静态类图

24a5bc1d04741b80c305ae7a045a4f36.png

希望本文所述对大家java程序设计有所帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/523467.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

联想成立数据智能事业部,前京东蓝烨回归;华为或已向多国知识产权组织提交「鸿蒙」商标申请……...

关注并标星星CSDN云计算极客头条&#xff1a;速递、最新、绝对有料。这里有企业新动、这里有业界要闻&#xff0c;打起十二分精神&#xff0c;紧跟fashion你可以的&#xff01;每周三次&#xff0c;打卡即read更快、更全了解泛云圈精彩newsgo go go 混合动力电动飞机Ampaire 33…

java铃声类_java多线程抓取铃声多多官网的铃声数据

一直想练习下java多线程抓取数据。有天被我发现&#xff0c;铃声多多的官网(http://www.shoujiduoduo.com/main/)有大量的数据。通过观察他们前端获取铃声数据的ajaxhttp://www.shoujiduoduo.com/ringweb/ringweb.php?typegetlist&listid{类别ID}&page{分页页码}很容易…

Spark精华问答 | RDD的核心概念是什么?

Hadoop再火&#xff0c;火得过Spark吗&#xff1f;今天我们继续关于Spark的精华问答吧。1Q&#xff1a;RDD的核心概念是什么&#xff1f;A&#xff1a;Client&#xff1a;客户端进程&#xff0c;负责提交作业到Master。Master:Standalone模式中主控节点&#xff0c;负责接收Cli…

用科技讲好中国历史故事,腾讯携手秦陵“玩儿转”数字化!

戳蓝字“CSDN云计算”关注我们哦&#xff01;众所周知&#xff0c;秦始皇陵及兵马俑坑一早就被联合国教科文组织批准列入《世界遗产名录》&#xff0c;并同时被誉为“世界第八大奇迹”&#xff0c;逐渐成长为中国古代辉煌文明的一张金字名片。与此同时&#xff0c;近年来秦陵博…

Tomcat10 开机启动 Linux环境

文章目录1. 切换用户2. 编辑3. 赋予权限4. 重启服务器5. 验证1. 切换用户 请切换到root用户执行&#xff0c;普通用户自启动无权限 su - root2. 编辑 vim /etc/rc.d/rc.local# 添加内容 source /etc/profile touch /var/lock/subsys/local /app/apache-tomcat-10.0.10/bin/s…

开源“大地震”下,华为如何复制 Google 模式?

戳蓝字“CSDN云计算”关注我们哦&#xff01;作者 | 郭芮出品 | CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;回首刚刚过去的五月&#xff0c;注定会给很多技术人留下浓墨重彩的一笔。2018 年 4 月&#xff0c;曾经占据智能手机全球份额第九、美国第四大智能手机供应商…

Spring精华问答 | 什么是YAML?

Spring框架是一个开源的Java平台,它提供了非常容易,非常迅速地开发健壮的Java应用程序的全面的基础设施支持。今天就让我们一起来看看关于Spring的精华问答吧。1Q&#xff1a;如何在自定义端口上运行Spring Boot应用程序&#xff1f;A&#xff1a;为了在自定义端口上运行Spring…

Sublime Test3 添加一键格式化XML文件插件

文章目录1. 下载地址&#xff1a;2. 快捷键&#xff1a;3. 在线格式化xml json插件1. 下载地址&#xff1a; 下载链接提取码https://pan.baidu.com/s/1zovLp4BCJmreAYe83EionAq0vq 2. 快捷键&#xff1a; 快捷键说明CtrlL选择整行&#xff08;按住-继续选择下行&#xff09;C…

java获得jsp的name注解_记录Java注解在JavaWeb中的一个应用实例

概述在学习注解的时候&#xff0c;学了个懵懵懂懂。学了JavaWeb之后&#xff0c;在做Demo项目的过程中&#xff0c;借助注解和反射实现了对页面按钮的权限控制&#xff0c;对于注解才算咂摸出了点味儿来。需求以"角色列表"页面为例&#xff0c;该页面包含"新建&…

企业实战_03_MyCat下载、安装、启动

接上一篇&#xff1a;企业实战_02_MyCat基本元素 https://gblfy.blog.csdn.net/article/details/118770154 Mycat是一个广受好评的数据库中间件&#xff0c;主要应用场景&#xff1a;主从复制、读写分离、垂直拆分、水平扩展、热备、分表分库等。 前言&#xff1a; MyCat基于jd…

微服务的历史与陷阱

戳蓝字“CSDN云计算”关注我们哦&#xff01;作者 | 李运华出品 | 技术琐话微服务是近几年非常火热的架构设计理念&#xff0c;大部分人认为是MartinFlower提出了微服务概念&#xff0c;但事实上微服务概念的历史要早得多&#xff0c;也不是Martin Flower创造出来的&#xff0c…

java加锁多线程改为单线程_GUI为什么不设计为多线程(用户事件和底层事件的流程是相反的,每层都加锁效率太低,共用一把锁那就是单线程)...

在我们这批新人转正评审的时候&#xff0c;我师父问了我的小伙伴一个问题&#xff1a;为什么一些更新界面的方法只能在主线程中调用&#xff1f;师父没有问我这个问题&#xff0c;让知其然但不知其所以然的我有种侥幸逃过一难的心情。我想如果回答那是因为Android GUI库是单线程…

行啊,人工智能玩大了!

戳蓝字“CSDN云计算”关注我们哦&#xff01;是的 &#xff0c;你没猜错&#xff01;就是人工智能&#xff01;AI的炽手可热程度和重要性无需多提。最近&#xff0c;笔者在网上发现了一个报告&#xff0c;报告名字&#xff1a;《BAT人工智能领域人才发展报告》&#xff0c;发现…

java xml注入bean_Spring实战之通过XML装配bean

尽管Spring长期以来确实与XML有着关联&#xff0c;但现在需要明确的是&#xff0c;XML不再是配置Spring的唯一可选方案。Spring现在有了强大的自动化配置和基于Java的配置&#xff0c;XML不应该再是你的第一选择了。不过&#xff0c;鉴于已经存在那么多基于XML的Spring配置&…

Docker 存储选型,这些年我们遇到的坑

戳蓝字“CSDN云计算”关注我们哦&#xff01;技术头条&#xff1a;干货、简洁、多维全面。更多云计算精华知识尽在眼前&#xff0c;get要点、solve难题&#xff0c;统统不在话下&#xff01;随着Docker 容器技术的不断发展和业内对Docker 的使用不断深入&#xff0c;大家已经不…

mysql主从复制之异常解决--- Slave_IO_Running: NO

关于 Slave_IO_Running: NO 的错误其实有很多原因&#xff0c; 文章目录1. 解决问题的思路2. 异常信息3. 问题定位&#xff1a;由于uuid相同&#xff0c;而导致触发此异常4. 解决方案5. 服务器背景6. 具体解决方案7. 重新启动mysql8. 登录mysql&#xff0c;重启slave&#xff0…

企业实战_11_MyCat垂直拆分相关配置

接上一篇&#xff1a;企业实战_10_MyCat Mysql 主复制总结 https://gblfy.blog.csdn.net/article/details/118652742 文章目录一、准备工作1. 实现思路2. 配置MyCat垂直分库3. 环境配置4. 在master节点创建mycat用户5. 赋予操作数据库权限二、schema.xml文件配置2.1. 基础模板 …

K8S精华问答 | 如何监控部署在Docker容器上的应用程序?

kubernetes&#xff0c;简称K8S&#xff0c;是用8代替8个字符“ubernete”而成的缩写。是一个开源的&#xff0c;用于管理云平台中多个主机上的容器化的应用&#xff0c;Kubernetes的目标是让部署容器化的应用简单并且高效&#xff08;powerful&#xff09;,Kubernetes提供了应…

带你全面了解Http和Https

戳蓝字“CSDN云计算”关注我们哦&#xff01;作者: 左大人 | 来源 公众号 程序员小乐来源&#xff1a;jianshu.com/p/27862635c07700 前言 Http和Https属于计算机网络范畴&#xff0c;但作为开发人员&#xff0c;不管是后台开发或是前台开发&#xff0c;都很有必要掌握它们。在…

企业实战_05_MyCat用户密码加密

接上一篇:企业实战_04_MyCat常用配置文件详解 https://gblfy.blog.csdn.net/article/details/100112080 文章目录1. 加密简述2. 加密目录3. 执行加密4. 添加加密属性5. 添加密文6. 测试是否可用声明&#xff1a;需要提前安装mysql Linux centos7 安装 MySQL5.7.x 1. 加密简述 …