欢迎大家提出意见,一起讨论!
转载请标明是引用于 http://blog.csdn.net/chenyujing1234
例子代码:(编译工具:Eclipse)
http://www.rayfile.com/zh-cn/files/2a49656e-91da-11e1-a750-0015c55db73d/
参考书籍: <<软件秘笈-----设计模式那点事>>
责任链模式(Chain of Responsibility Pattern),是一种对象的形为模式。在责任链模式中,很多对象由每一个对象对其下家的引用而连接起来形成一条链。
客户端应用请求在这个链上传递,直到链上某一个对象决定处理此请求。
责任链模式涉及的角色如下。
(1)抽象处理者角色(Handler):定义出一个处理请求的接口。如果需要,接口可以定义出一个方法,以设定和返回下家的引用。这个角色通常由一个Java抽象类或Java接口实现。
(2)具体处理者角色(ConcreteHandler):具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。
下面以学生请假的流程为例进行说明.
来一起分析学生请假的流程。
(1)小学生生病了,发出请假请求。
(2)请假请求首先发给班长,看看班长能否处理。如果班长能够处理,则由班长批准请假;否则,交给老师处理。
(3)老师接到学生请假请求,首先判断病情是否严重。如果是一般的小病,则老师批准请假;否则,交给校长处理。
(4)校长接到学生请假请求,核实属实,则给予请假批准。
在一般情况下是如何分析解决这样的问题的。如图14-2所示,为一般情况学生请假关系类图。
根据设计模式中的依赖倒置原则,即面向抽象编程,而不要而向实现编程,首先定义两个接口:学生请假接口IStudent和请求处理接口IHandler。
在学生请假接口中存在两个方法:分别为病情状态(这个用来标识由谁来处理)和请求消息。而IHandler请求处理接口很简单,就是接收学生请假请求进行处理。
为了更好地扩展我们再增加一不念旧恶请求的抽象处理者AbstractHandler,该抽象处理者实现IHandler接口,实现学生请求处理接口方法,
然后使用模板方法,由子类实现具体的处理过程。
班长、老师和校长都继承抽象处理者AbstractHandler。
责任链的实现关键在于消息在链条上的传递,需要做到以下几点内容:
(1)在处理者中要含有链条中下一节点的引用。在抽象处理者AbstractHandler中增加一个IHandler类型的私有属性,用于保存对下家处理者的引用。
(2)每一个消息处理者都应该含有一个处理消息的标记位,用来标识当前处理者含有处理消息的级别。
(3)最后一点,也是最重要的一点就是,处理消息的方法需要链条化。
根据上面的内容修改完善静态类图,如图
下面我们就开始实现吧!
首先,我们创建学生请求接口IStudent,该接口类中含有两个接口方法:一个是获得学生病情状态,另一个是获取学生请假内容。
/** * 学生接口 * * @author * */ public interface IStudent { /** * 获得学生病情状态 * * 0:小事(班长就可以处理) * * 1:班长处理不了 老师能处理的事 * * 2:老师处理不了 校长能处理的事 * * */ public int getState(); /** * 获得学生请假消息 * * @return */ public String getRequestMessage(); }
在学生请假实现类中,定义了两个私有属性:病情状态和请假内容,通过构造方法传入。
/** * 学生实现类 * * @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; } }
/** * 抽象处理者接口 * * @author * */ public interface IHandler { // 处理请求 public void handleRequest(IStudent student); // 设置下一个处理者 public void setHandler(IHandler handler); }
它的存在是将处理学生的请求过程抽象化,而对学生请假请求的处理措施则由具体的子类来实现。
/** * 抽象处理者 * * @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; } }
需要实现处理方法process
/** * 班长处理者 * * @author * */ public class SquadLeaderHandler extends AbstractHandler { public SquadLeaderHandler() { super(0); } // 子类具体处理请求 @Override public void process(IStudent student) { System.out.println("班长 批复:" + student.getRequestMessage()); } }
/** * 老师处理者 * * @author * */ public class TeacherHandler extends AbstractHandler { public TeacherHandler() { super(1); } // 子类具体处理请求 @Override public void process(IStudent student) { System.out.println("老师 批复:" + student.getRequestMessage()); } }
/** * 校长处理者 * * @author * */ public class SchoolMasterHandler extends AbstractHandler { public SchoolMasterHandler() { super(2); } // 子类具体处理请求 @Override public void process(IStudent student) { System.out.println("校长 批复:" + student.getRequestMessage()); } }
创建Client客户端应用程序,首先需要创建三个请求处理者:班长、老师和校长;
然后处理者根据学生病情的状态,对学生的请假分别做出不同的处理。
为了符“开-闭”原则(即做到扩展开放,对修改关闭的),这里处理者是变化的部分,可能会增加,我们需要抽象和封装。
于是采用外观模式,增加一个外观,让外观与处理者对象打交道,而客户端应用程序调用外观处理学生请假请求。
/** * 设置责任链关联 * * @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); } }
客户端如下:
/** * 主应用程序 * * @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"); } } }
================================================================================================
总结:
一、设计原则
1、"开-闭"原则
它是设计模式的核心原则,在每一个设计模式中都有体现,责任链中的"开-闭"原则体现在可以动态地扩展责任链当中的处理节点。
而无须改动客户端应用,程序结构更加清晰,同时也大大保证了系统运行的稳定性。
2、单一职责原则.
消息处理者只完成各自的本职工作,尽量做到功能单一,这为后期的测试维护工作带来方便,每一个类的功能单一,我们可以一定
定位问题所在,节省了找错时间。