JAVA设计模式学习20——责任链模式

2019-03-07 13:56|来源: 网络

责任链(Chain of Responsibility)模式:责任链模式是对象的行为模式。使多个对象都有机会处理请求,从而避免请求的发送者和接受者直接的耦合关系。将这些对象连成一条链,沿着这条链传递该请求,直到有一个对象处理它为止。责任链模式强调的是每一个对象及其对下家的引用来组成一条链,利用这种方式将发送者和接收者解耦,类图如下:

通过上图可以看出责任链模式有两个角色:    
抽象处理者(Handler)角色:定义一个请求的接口。如果需要可以定义个一个方法用来设定和返回下家对象的引用。    

具体处理者(ConcreteHandler)角色:如果可以处理就处理请求,如果不能处理,就把请求传给下家,让下家处理。也就是说它处理自己能处理的请求且可以访问它的下家。  


上述模式的测试代码如下:    
Java代码
  1. package chainOfResp;  

  2. /**

  3. *

  4. *作者:alaric

  5. *时间:2013-8-17上午11:01:58

  6. *描述:抽象处理角色

  7. */  

  8. public abstract class Handler {  

  9.  

  10.    protected Handler successor;  

  11.    /**

  12.     *

  13.     *作者:alaric

  14.     *时间:2013-8-17上午11:04:22

  15.     *描述:处理方法

  16.     */  

  17.    public abstract void handlerRequest(String condition);  

  18.      

  19.      

  20.    public Handler getSuccessor() {  

  21.        return successor;  

  22.    }  

  23.    public void setSuccessor(Handler successor) {  

  24.        this.successor = successor;  

  25.    }    

  26.      

  27. }  

Java代码
  1. package chainOfResp;  

  2. /**

  3. *

  4. *作者:alaric

  5. *时间:2013-8-17上午11:25:54

  6. *描述:具体处理角色

  7. */  

  8. public class ConcreteHandler1 extends Handler {  

  9.  

  10.    @Override  

  11.    public void handlerRequest(String condition) {  

  12.        // 如果是自己的责任,就自己处理,负责传给下家处理  

  13.        if(condition.equals("ConcreteHandler1")){  

  14.            System.out.println( "ConcreteHandler1 handled ");  

  15.            return ;  

  16.        }else{  

  17.            System.out.println( "ConcreteHandler1 passed ");  

  18.            getSuccessor().handlerRequest(condition);  

  19.        }  

  20.    }  

  21.  

  22. }  

Java代码
  1. package chainOfResp;  

  2. /**

  3. *

  4. *作者:alaric

  5. *时间:2013-8-17上午11:25:54

  6. *描述:具体处理角色

  7. */  

  8. public class ConcreteHandler2 extends Handler {  

  9.      

  10.    @Override  

  11.    public void handlerRequest(String condition) {  

  12.        // 如果是自己的责任,就自己处理,负责传给下家处理  

  13.        if(condition.equals("ConcreteHandler2")){  

  14.            System.out.println( "ConcreteHandler2 handled ");  

  15.            return ;  

  16.        }else{  

  17.            System.out.println( "ConcreteHandler2 passed ");  

  18.            getSuccessor().handlerRequest(condition);  

  19.        }  

  20.    }  

  21.  

  22. }  

Java代码
  1. package chainOfResp;  

  2. /**

  3. *

  4. *作者:alaric

  5. *时间:2013-8-17上午11:25:54

  6. *描述:具体处理角色

  7. */  

  8. public class ConcreteHandlerN extends Handler {  

  9.  

  10.    /**

  11.     * 这里假设n是链的最后一个节点必须处理掉

  12.     * 在实际情况下,可能出现环,或者是树形,

  13.     * 这里并不一定是最后一个节点。

  14.     *

  15.     */  

  16.    @Override  

  17.    public void handlerRequest(String condition) {  

  18.  

  19.        System.out.println( "ConcreteHandlerN handled");  

  20.          

  21.    }  

  22.  

  23. }  

Java代码
  1. package chainOfResp;  

  2. /**

  3. *

  4. *作者:alaric

  5. *时间:2013-8-17上午10:59:06

  6. *描述:测试类

  7. */  

  8. public class Client {  

  9.  

  10.    /**

  11.     *作者:alaric

  12.     *时间:2013-8-17上午10:58:58

  13.     *描述:

  14.     */  

  15.    public static void main(String[] args) {  

  16.      

  17.        Handler handler1 = new ConcreteHandler1();  

  18.        Handler handler2 = new ConcreteHandler2();  

  19.        Handler handlern = new ConcreteHandlerN();  

  20.          

  21.        //链起来  

  22.        handler1.setSuccessor(handler2);  

  23.        handler2.setSuccessor(handlern);  

  24.          

  25.        //假设这个请求是ConcreteHandler2的责任  

  26.        handler1.handlerRequest("ConcreteHandler2");  

  27.          

  28.          

  29.    }  

  30.  

  31. }  

     
举这样一个例子,在玩具工厂的生产车间,流水线就是一条责任链,假如一个玩具飞机有外壳装配员,引擎装配员,螺旋桨装配员,模型包装员组成。当这个物件飞机流到谁那里,谁就负责安装他负责的这一部分,这部分安装完成后流到下一个环节,知道所有环境完成。这个是一生成的责任链。还有一个质量检测链,质量检测也分多部,外壳检测,引擎检测,螺旋桨检测,包装检测。当产品留到检测员那里检测自己负责的那一块,如果有问题直接拎出来,如果没问题则传给下一个检测员,直到所有检测完成。这两个都是责任链,但是区别是,生成责任链每个人都会处理,并处理一部分;而质量检测责任链经过判断,要么处理掉,要么不处理流下去。这就是责任链的两种分类,后一种叫做纯的责任链,前一种叫做不纯的责任链,纯的责任链在实际应用中很少存在,常见的为不纯的责任链,上面的模型是模拟纯的责任链来处理的。    
     
责任链模式在现实中使用的很多,常见的就是OA系统中的工作流。 在java中的实际应用有Servlet中的过滤器(Filter),Struts2的拦截器(Interceptor)。Struts2本身在Servlet中也是以Filter的形式出现的,所以Struts2的结构图中,也可以明显看出Filter和Interceptor这两条链的存在。    


 可以看出它们每个节点都可以做一些事情,所以不算一个纯的责任链。
 在上面提到了OA系统,那么我们再模拟一下OA系统中请假审批流程,假如员工直接上司为小组长,小组长直接上司项目经理,项目经理直接上司部门经理,部门经理直接上司总经理。公司规定请假审批如下:
 请假时间为t,时间单位day,简写d:
 t<  0.5d,小组长审批;
 t>=0.5d,t<2,项目经理审批;
 t>=2,t<5部门经理审批;
 t>=5总经理审批;
 审批时序图如下:
     
     


用代码描述:  

Java代码
  1. package chainOfResp.example;  

  2. /**

  3. *

  4. *作者:alaric

  5. *时间:2013-8-17下午1:02:51

  6. *描述:审批处理抽象类

  7. */  

  8. public abstract class Handler {  

  9.  

  10.    protected Handler handler;  

  11.  

  12.    /**

  13.     *

  14.     *作者:alaric

  15.     *时间:2013-8-17下午1:07:40

  16.     *描述:审批

  17.     */  

  18.    public abstract boolean approve(double day);  

  19.      

  20.    public Handler getHandler() {  

  21.        return handler;  

  22.    }  

  23.    public void setHandler(Handler handler) {  

  24.        this.handler = handler;  

  25.    }  

  26.      

  27. }  

Java代码
  1. package chainOfResp.example;  

  2.  

  3.  

  4. public class GroupLeader extends Handler {  

  5.  

  6.    @Override  

  7.    public boolean approve(double day) {  

  8.        if(day<0.5){  

  9.            System.out.println("小组长审批通过");  

  10.            return true;  

  11.        }else {  

  12.            System.out.println("小组长传给了他的上司");  

  13.            return getHandler().approve(day);  

  14.        }  

  15.    }  

  16.  

  17.  

  18. }  

Java代码
  1. package chainOfResp.example;  

  2.  

  3.  

  4. public class ProjectManager extends Handler {  

  5.  

  6.    @Override  

  7.    public boolean approve(double day) {  

  8.        if(day<2){  

  9.            System.out.println("项目经理审批通过");  

  10.            return true;  

  11.        }else {  

  12.            System.out.println("项目经理传给了他的上司");  

  13.            return getHandler().approve(day);  

  14.        }  

  15.    }  

  16.  

  17.  

  18. }  

Java代码
  1. package chainOfResp.example;  

  2.  

  3.  

  4. public class DepartmentManager extends Handler {  

  5.  

  6.    @Override  

  7.    public boolean approve(double day) {  

  8.        if(day<5){  

  9.            System.out.println("部门经理审批通过");  

  10.            return true;  

  11.        }else {  

  12.            System.out.println("部门经理传给了他的上司");  

  13.            return getHandler().approve(day);  

  14.        }  

  15.    }  

  16.  

  17.  

  18. }  

Java代码
  1. package chainOfResp.example;  

  2.  

  3.  

  4. public class CEO extends Handler {  

  5.  

  6.    @Override  

  7.    public boolean approve(double day) {  

  8.            System.out.println("部门经理审批通过");  

  9.            return true;  

  10.          

  11.    }  

  12.  

  13. }  

Java代码
  1. package chainOfResp.example;  

  2. /**

  3. *

  4. *作者:alaric

  5. *时间:2013-8-17下午12:54:51

  6. *描述:测试类,首先来创建责任链,然后发出请求模拟员工来请假

  7. */  

  8. public class Client {  

  9.  

  10.    /**

  11.     *作者:alaric

  12.     *时间:2013-8-17下午12:54:44

  13.     *描述:

  14.     */  

  15.    public static void main(String[] args) {  

  16.  

  17.        //创建节点  

  18.        GroupLeader gl = new GroupLeader();  

  19.        ProjectManager pm = new ProjectManager();  

  20.        DepartmentManager dm = new DepartmentManager();  

  21.        CEO ceo = new CEO();  

  22.        //建立责任链  

  23.        gl.setHandler(pm);  

  24.        pm.setHandler(dm);  

  25.        dm.setHandler(ceo);  

  26.          

  27.        //向小组长发出申请,请求审批4天的假期  

  28.        gl.approve(4D);  

  29.          

  30.  

  31.    }  

  32.  

  33. }  



运行结果:      
小组长传给了他的上司      
项目经理传给了他的上司      
部门经理审批通过      
         
  这里模拟的是一个理想的状态,所以是一个纯的责任链;在实际当中,可能小组长签字,项目经理签字...一堆的签字,而不是不参与请求的处理。      
  责任链模式的优点是调用者不需知道具体谁来处理请求,也不知道链的具体结构,降低了节点域节点的耦合度;可在运行时动态修改链中的对象职责,增强了给对象指派职责的灵活性;缺点是没有明确的接收者,可能传到链的最后,也没得到正确的处理。      
     
 
     

 
转自:http://alaric.iteye.com/blog/1926447

相关问答

更多
  • 其实我相信你做了3年的java一定了解你所说的设计模式和反射机制在程序早已用过了的把,只是自己平时没注意;设计模式主要是用项目管理,让人看起来通俗易懂.反射机制用到的地方呢也比较多,在用properties和JFreeChart等地方都用到.
  • 设计模式如果要按顺序来说的话,肯定是先工厂然后再单例,多例,适配器!信我的!
  • 模式开扩了我们的视野,强化了我们面向对象编程的思维方式 提高代码的复杂度为代价来增强灵活性、可复用性 工厂模式根据工厂模式实现的类可以根据提供的数据 生成一组类中某一个类的实例,通常这组类有一个公共的 抽象父类或接口并且实现了相同的方法,但是这些方法针对不同 的数据进行了不同的操作。 首先需要定义一个基类,该类的子类通过不同的方法实现了 基类中的方法,然后需要定义一个工厂类,工厂类可以根据 条件生成不同子类的实例。 得到实例后,可以调用基类的方法而不必考虑到底 返回的是哪个子类的实例。 Factory(工厂 ...
  • 马学兵视频,W3C 教程,硅谷动力 视频教程等 先看视频,然后跟着做一遍。 最后下载一个 源码,尝试着模仿做几个 基本算入门了
  • 你是准备学习使用 还是说研究它的底层实现机制这些东西? 如果只是使用 可以暂时不了解这些 ,你也没有这么多精力来了解这么多 你先将框架中的东西用熟练 然后再去了解这些也不迟 spring 的 IOC aop hibernate的 延迟加载 缓存 ,mvc这些学习都需要学习 其实你学习不学习这几个框架都可以对设计模式进行学习 设计模式在日常的版本开发中好处很多 而且在面试的时候 考官也会问设计模式方面的知识
  • 一般来说电驴(verycd)里面可以下载,那里面的资源很多。希望这个对你有帮助
  • 设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。 java设计模式是当你在实际的系统当中遇到重构或者扩展的时候采取的一种对现有系统影响最小的一种措施。当然并不是一定要学这个东西,就像一个没上过学的人和上过学的人,在个人修养上面存在一定的差异,但是他们都 ...
  • 你应该能够删除Processor processor上的泛型Processor processor Processor processor为Processor processor ,它将错误转换为关于原始类型的警告,您可以使用@SuppressWarnings("rawtypes")静音 .ifPresent(processor -> ((Processor) processor).proces ...
  • 这里是相关的代码 : // Post the LogRecord to all our Handlers, and then to // our parents' handlers, all the way up the tree. Logger logger = this; while (logger != null) { Handler targets[] = logger.getHandlers(); //... if (!logger.getUseParentHandl ...
  • 你是对的。 Java中的异常处理基于责任链模式在此模式中: 发件人不知道链中的哪个对象将服务于其请求 链中的每个节点可以决定提供请求 - >捕获异常和 用特定于应用程序的异常包装它 每个节点都可以转发请求 - >将异常抛给直接调用者 没有节点可以为请求提供服务 - >将作业留给调用者 因此,异常处理是一种责任链模式 You are right. Exception handling in Java is based on Chain of responsibility pattern In this pat ...