设计模式-责任链模式

 

1 模式动机

为了降低系统的耦合度,将事件请求者和接收者解耦,我们可以使用命令模式来设计系统。通过增加不同的命令对象,不仅可以解耦,也可以有效解决发送和接收处理速度不一样的问题。

 

2 模式定义

责任链模式(Chain of Responsibility Pattern):将多个对象连成一条链,沿着这条链传递请求,直到有一个对象处理它为止,使得多个对象都有机会处理该请求。

 

3 模式分析

Handler处理者接口:

    声明处理请求的接口。

ConcreteHandler具体处理者类:

    实现处理请求的接口,指定下一处理者。

Client:

    调用客户。

类图如下所示:

 

4 实例演示

 1 package com.pattern.responsibility;
 2 
 3 public abstract class Handler {
 4     public Handler successor = null;
 5 
 6     public abstract boolean canHandle();
 7 
 8     public abstract void handle();
 9 
10     public void handleRequest() {
11         if(canHandle()) {
12             handle();
13         } else {
14             getSuccessor().handleRequest();
15         }
16     }
17 
18     public Handler getSuccessor() {
19         if(successor==null) {
20             successor = new EmptyHandler();
21         }
22         return successor;
23     }
24 
25     public void setSuccessor(Handler successor) {
26         this.successor = successor;
27     }
28 }

 

 1 package com.pattern.responsibility;
 2 
 3 public class CommonHandler extends Handler {
 4     @Override
 5     public boolean canHandle() {
 6         // 是否可以处理请求
 7         System.out.println("Common not handle...");
 8         return false;
 9     }
10 
11     @Override
12     public void handle() {
13         System.out.println("Common handle...");
14     }
15 }

 

 1 package com.pattern.responsibility;
 2 public class SpecialHandler extends Handler {
 3     @Override
 4     public boolean canHandle() {
 5         // 具体handler实现
 6         System.out.println("Special not handle...");
 7         return false;
 8     }
 9 
10     @Override
11     public void handle() {
12         System.out.println("Special handle...");
13     }
14 }

 

 1 package com.pattern.responsibility;
 2 
 3 public class ExtendHandler extends Handler {
 4     @Override
 5     public boolean canHandle() {
 6         // 是否可以处理请求
 7         return true;
 8     }
 9 
10     @Override
11     public void handle() {
12         System.out.println("Extend handle...");
13     }
14 }

 

 1 package com.pattern.responsibility;
 2 
 3 public class EmptyHandler extends Handler {
 4     @Override
 5     public boolean canHandle() {
 6         // 是否可以处理请求
 7         return true;
 8     }
 9 
10     @Override
11     public void handle() {
12         // TODO Auto-generated method stub
13     }
14 }

 

 1 package com.pattern.responsibility;
 2 
 3 public class Client {
 4     public static void main(String args[]) {
 5         CommonHandler commonHandler = new CommonHandler();
 6         SpecialHandler specialHandler = new SpecialHandler();
 7         ExtendHandler extendHandler = new ExtendHandler();
 8 
 9         commonHandler.setSuccessor(specialHandler);
10         specialHandler.setSuccessor(extendHandler);
11 
12         commonHandler.handleRequest();
13     }
14 }

 

5 纯责任链与不纯责任链

    纯责任链:

1 handler能处理请求时,停止调用下一个handler。当handler不能处理请求时,继续调用下一个handler。只能在两个行为中选择一个,一是承担责任,二是把责任推给下家。

(好比男人要么做个有责任感的人,要么做个推卸责任的人)

2 一个请求必须被某一个处理者对象接收。

例如:工厂产品的质量检查流水线,如果出现问题,就直接将产品拿出来。如果通过检查,则传递给下一个检查员。

不纯责任链:

1 承担一部分责任又把责任传到下一个处理者(好比工厂的流水线,每处理完一道工序,交给下一个人处理)。

2 一个请求可以不被任何处理者接收。

例如:工厂产品的生产流水线,每个人都会处理一部分,然后交给下一个人。

 

6 优缺点

优点:

1 可以灵活方便的将处理者连接成一条链,满足不同的需求。

2 将请求者与处理者解耦,提高灵活性。

 

缺点:

1 if...else...缺点一样,在找到正确逻辑处理前,要遍历每一个逻辑判断,当责任链的对象过多时,会影响性能。

 

7 适用环境

1 有多个对象可以处理同一请求,处理请求的时机可以放在运行时确定。

 

8 总结

1 责任链模式最大的好处:可以根据需求组织对应的责任链处理请求,调用某个处理者即可,不用知道它内部的实现(它可以自己处理,也可以委托其它处理者处理)

 

9 问题

1 为什么不将处理器组成一个List,然后按顺序处理请求?

  这样请求可能被处理多次,在某些业务场景是不合适的(比如付款单发给多个付款者,则会发生多次付款)。这些场景处理者处理完毕后,不需要下一个处理者接着处理,这样就不能用列表,而是通过责任链处理,当不需要往下传递时,马上终止处理。

2 责任链模式最可能在什么场景下使用?

  当业务逻辑中包含多个ifelse分支,代码看上去很糟糕时,可以考虑使用责任链模式将条件判断逻辑分散到多个处理者对象中。

 

posted on 2017-02-23 11:51  天涯之帆  阅读(1761)  评论(0编辑  收藏  举报

导航