分享

责任链模式——学生请假

 WindySky 2018-02-25

一模式定义

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

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

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

 

二模式举例

1模式分析

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


 

2责任链模式静态类图


 

3代码示例

3.1学生接口一IStudent

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

3.2学生实现一Student

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

3.3抽象处理接口一IHandler

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

3.4抽象处理者一AbstractHandler

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

3.5班长一SquadLeaderHandler

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

3.6老师一TeacherHandler

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

3.7校长一SchoolMasterHandler

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

3.8外观类一ProcessHandler

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

3.9客户端一Client

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

 4运行结果

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

请求上级领导批复!

请求上级领导批复!

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

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

 

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

请求上级领导批复!

请求上级领导批复!

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

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

 

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

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

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

三该模式设计原则

1"开-闭"原则

2单一职责原则

 

四使用场合

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

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

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

五责任链模式静态类图


 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多