查看: 219|回复: 0

[Java代码] Java使用责任链模式处理学生请假问题详解

发表于 2018-5-6 08:59:42

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

一. 模式定义

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

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

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

二. 模式举例

1 模式分析

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

2 责任链模式静态类图

3 代码示例

3.1学生接口一IStudent

  1. package com.demo.chain.message;
  2. /**
  3. * 学生接口
  4. *
  5. * @author
  6. *
  7. */
  8. public interface IStudent {
  9. /**
  10. * 获得学生病情状态
  11. *
  12. * 0:小事(班长就可以处理)
  13. *
  14. * 1:班长处理不了 老师能处理的事
  15. *
  16. * 2:老师处理不了 校长能处理的事
  17. *
  18. *
  19. */
  20. public int getState();
  21. /**
  22. * 获得学生请假消息
  23. *
  24. * @return
  25. */
  26. public String getRequestMessage();
  27. }
复制代码

3.2学生实现一Student

  1. package com.demo.chain.message;
  2. /**
  3. * 学生实现类
  4. *
  5. * @author
  6. *
  7. */
  8. public class Student implements IStudent {
  9. // 病情的大小状态
  10. private int state = -1;
  11. // 请假消息
  12. private final String message;
  13. public Student(int state, String message) {
  14. this.state = state;
  15. this.message = message;
  16. }
  17. /**
  18. * 获得学生请假状态
  19. *
  20. * 0:小事(班长就可以处理)
  21. *
  22. * 1:班长处理不了 老师能处理的事
  23. *
  24. * 2:老师处理不了 校长能处理的事
  25. *
  26. *
  27. */
  28. public int getState() {
  29. return this.state;
  30. }
  31. /**
  32. * 获得学生请假消息
  33. *
  34. * @return
  35. */
  36. public String getRequestMessage() {
  37. return this.message;
  38. }
  39. }
复制代码

3.3抽象处理接口一IHandler

  1. package com.demo.chain.handle;
  2. import com.demo.chain.message.IStudent;
  3. /**
  4. * 抽象处理者接口
  5. *
  6. * @author
  7. *
  8. */
  9. public interface IHandler {
  10. // 处理请求
  11. public void handleRequest(IStudent student);
  12. // 设置下一个处理者
  13. public void setHandler(IHandler handler);
  14. }
复制代码

3.4抽象处理者一AbstractHandler

  1. package com.demo.chain.handle;
  2. import com.demo.chain.message.IStudent;
  3. /**
  4. * 抽象处理者
  5. *
  6. * @author
  7. *
  8. */
  9. public abstract class AbstractHandler implements IHandler {
  10. // 下一个处理者
  11. private IHandler handler;
  12. // 请假级别
  13. private int state = -1;
  14. // 构造方法 设置级别
  15. public AbstractHandler(int state) {
  16. this.state = state;
  17. }
  18. // 处理请求 交由子类负责进行具体的处理
  19. public abstract void process(IStudent student);
  20. // 处理请求
  21. public void handleRequest(IStudent student) {
  22. // 如果学生对象存在
  23. if (student != null) {
  24. if (this.state == student.getState()) {
  25. // 如果请假级别和当前一致 则当前对象进行处理
  26. this.process(student);
  27. } else {
  28. if (this.handler != null) {
  29. System.out.println("请求上级领导批复!");
  30. // 如果当前对象处理不了 则交给下一个处理者进行处理
  31. this.handler.handleRequest(student);
  32. }
  33. }
  34. }
  35. }
  36. // 设置下一个处理者
  37. public void setHandler(IHandler handler) {
  38. this.handler = handler;
  39. }
  40. }
复制代码

3.5班长一SquadLeaderHandler

  1. package com.demo.chain.handle;
  2. import com.demo.chain.message.IStudent;
  3. /**
  4. * 抽象处理者
  5. *
  6. * @author
  7. *
  8. */
  9. public abstract class AbstractHandler implements IHandler {
  10. // 下一个处理者
  11. private IHandler handler;
  12. // 请假级别
  13. private int state = -1;
  14. // 构造方法 设置级别
  15. public AbstractHandler(int state) {
  16. this.state = state;
  17. }
  18. // 处理请求 交由子类负责进行具体的处理
  19. public abstract void process(IStudent student);
  20. // 处理请求
  21. public void handleRequest(IStudent student) {
  22. // 如果学生对象存在
  23. if (student != null) {
  24. if (this.state == student.getState()) {
  25. // 如果请假级别和当前一致 则当前对象进行处理
  26. this.process(student);
  27. } else {
  28. if (this.handler != null) {
  29. System.out.println("请求上级领导批复!");
  30. // 如果当前对象处理不了 则交给下一个处理者进行处理
  31. this.handler.handleRequest(student);
  32. }
  33. }
  34. }
  35. }
  36. // 设置下一个处理者
  37. public void setHandler(IHandler handler) {
  38. this.handler = handler;
  39. }
  40. }
复制代码

3.6老师一TeacherHandler

  1. package com.demo.chain.impl;
  2. import com.demo.chain.handle.AbstractHandler;
  3. import com.demo.chain.message.IStudent;
  4. /**
  5. * 老师处理者
  6. *
  7. * @author
  8. *
  9. */
  10. public class TeacherHandler extends AbstractHandler {
  11. public TeacherHandler() {
  12. super(1);
  13. }
  14. // 子类具体处理请求
  15. @Override
  16. public void process(IStudent student) {
  17. System.out.println("老师 批复:" + student.getRequestMessage());
  18. }
  19. }
复制代码

3.7校长一SchoolMasterHandler

  1. package com.demo.chain.impl;
  2. import com.demo.chain.handle.AbstractHandler;
  3. import com.demo.chain.message.IStudent;
  4. /**
  5. * 校长处理者
  6. *
  7. * @author
  8. *
  9. */
  10. public class SchoolMasterHandler extends AbstractHandler {
  11. public SchoolMasterHandler() {
  12. super(2);
  13. }
  14. // 子类具体处理请求
  15. @Override
  16. public void process(IStudent student) {
  17. System.out.println("校长 批复:" + student.getRequestMessage());
  18. }
  19. }
复制代码

3.8外观类一ProcessHandler

  1. package com.demo.chain.process;
  2. import com.demo.chain.handle.IHandler;
  3. import com.demo.chain.impl.SchoolMasterHandler;
  4. import com.demo.chain.impl.SquadLeaderHandler;
  5. import com.demo.chain.impl.TeacherHandler;
  6. import com.demo.chain.message.IStudent;
  7. /**
  8. * 设置责任链关联
  9. *
  10. * @author
  11. *
  12. */
  13. public class ProcessHandler {
  14. // 班长处理者
  15. private final IHandler sqmshandler;
  16. // 老师处理者
  17. private final IHandler techhandler;
  18. // 校长处理者
  19. private final IHandler scmshandler;
  20. // 单例模式
  21. private static ProcessHandler processHandler = new ProcessHandler();
  22. /**
  23. * 构造方法建立请假处理责任链
  24. */
  25. private ProcessHandler() {
  26. // 创建处理对象
  27. // 班长
  28. this.sqmshandler = new SquadLeaderHandler();
  29. // 老师
  30. this.techhandler = new TeacherHandler();
  31. // 校长
  32. this.scmshandler = new SchoolMasterHandler();
  33. /**
  34. * 建立责任链
  35. */
  36. // 设置班长的下一个处理者:老师
  37. this.sqmshandler.setHandler(this.techhandler);
  38. // 设置老师的下一个处理者:校长
  39. this.techhandler.setHandler(this.scmshandler);
  40. }
  41. /**
  42. * 获得单例对象实例
  43. *
  44. * @return
  45. */
  46. public static ProcessHandler getInstance() {
  47. return processHandler;
  48. }
  49. /**
  50. * 发送请假请求
  51. *
  52. * @param message
  53. */
  54. public void sendMessage(IStudent student) {
  55. // 发送给第一个处理者:班长 处理
  56. this.sqmshandler.handleRequest(student);
  57. }
  58. }
复制代码

3.9客户端一Client

  1. package com.demo;
  2. import java.util.Random;
  3. import com.demo.chain.message.IStudent;
  4. import com.demo.chain.message.Student;
  5. import com.demo.chain.process.ProcessHandler;
  6. /**
  7. * 主应用程序
  8. *
  9. * @author
  10. *
  11. */
  12. public class Client {
  13. /**
  14. * @param args
  15. */
  16. public static void main(String[] args) {
  17. // 获得外观对象
  18. ProcessHandler processHandler = ProcessHandler.getInstance();
  19. // 创建随机数对象 用来随机产生学生对象
  20. Random random = new Random();
  21. for (int i = 0; i < 3; i++) {
  22. // 获得随机数
  23. int radom = random.nextInt(3);
  24. IStudent student = new Student(radom, "学生" + i + "生病了,要请假!");
  25. System.out.println("#################################");
  26. // 处理消息
  27. processHandler.sendMessage(student);
  28. System.out.println("#################################\n");
  29. }
  30. }
  31. }
复制代码

4 运行结果

#################################
请求上级领导批复!
请求上级领导批复!
校长 批复:学生0生病了,要请假!
#################################
#################################
请求上级领导批复!
请求上级领导批复!
校长 批复:学生1生病了,要请假!
#################################
#################################
班长 批复:学生2生病了,要请假!
#################################

三. 该模式设计原则

1"开-闭"原则

2单一职责原则

四. 使用场合

(1)有多个对象处理同一请求,具体由哪一个来处理还不确定,只有在运行时才确定哪个对象处理的情况。
(2)消息具有多个接收者,而接收对象又是不明确的情况。只需要向其中的一个对象发出消息,由其内部具体处理。
(3)同一消息的多个处理对象可能会动态增加或减少,需要动态地指定的情况。

五. 责任链模式静态类图

更多java相关内容感兴趣的读者可查看本站专题:《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总》

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



回复

使用道具 举报