首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

CoR 形式(另一种)

2012-10-30 
CoR 模式(另一种)CoR(Chain of Responsibility) ??职责链设计模式我在 两种 CoR(一)中讨论了传统的CoR实现

CoR 模式(另一种)

CoR(Chain of Responsibility) ??职责链设计模式

我在 两种 CoR(一)中讨论了传统的CoR实现:

但我感觉 让 每个处理器都持有后继处理器的引用,会增加处理器之间的耦合度.

?

下面是我的一些想法 和 具体实现:

(1)处理器 不持有 后继处理器的引用,引入一个新的角色 处理器容器(HandlerContainer),由容器管理每个处理器,并且这个处理器容器 也是一个处理器(实现了Handler接口),他的处理能力是容器里所有处理器的处理能力的和。

(2)一个处理器如果不能处理传递过来的请求,则抛出一个(CanNotHandleRequestException)异常,

?如果管理这个处理器的容器接受到这个异常,则将请求传递给容器中的下一个处理器。如果容器中的所有处理器都不能处理这个请求,则由容器抛出一个(CanNotHandleRequestException)异常。

?

实现:与传统CoR相比,处理器接口(Handler)不变,请求接口(Request)和实现类不变。

1,增加CanNotHandleRequestException异常类,当处理器不能处理传递过来的请求时就抛出这个异常。

?

public class CanNotHandleRequestException extends Exception{private static final long serialVersionUID = 1L;}

?

2,增加处理器容器类(HandlerContainer),处理器容器类也实现了处理器接口,他的处理能力是容器里所有处理器的处理能力的和。

?

public class HandlerContainer implements Handler{private List<Handler> handlers;public HandlerContainer(){handlers = new ArrayList<Handler>();} public boolean add(Handler handler){return this.handlers.add(handler);}public boolean remove(Handler handler){return this.handlers.remove(handler);}public void handleRequest(Request request) throws CanNotHandleRequestException{int length = this.handlers.size();for(int i = 0 ; i < length ; i++){Handler handler = handlers.get(i);try {handler.handleRequest(request);break;} catch (CanNotHandleRequestException e) {/* * 如果处理器容器里的所有处理器都不能处理该请求, * 则由容器抛出 CanNotHandleRequestException 异常。 */if(i == length-1) throw e;}}}}

?

3,实现处理器接口的实现类?HelpHandler?PrintHandler?,SaveHandler

????HelpHandler?处理 帮助请求(HelpRequest?

?

?

public class HelpHandler implements Handler{public void handleRequest(Request request) throws CanNotHandleRequestException {if(request instanceof HelpRequest){System.out.println("HelpHandler  handle "+request.getClass().getSimpleName());}elsethrow new CanNotHandleRequestException();}}

?

?PrintHandler?处理 打印请求(PrintRequest?

?

public class PrintHandler implements Handler{public void handleRequest(Request request) throws CanNotHandleRequestException{if(request instanceof PrintRequest){System.out.println("PrintHandler handle "+request.getClass().getSimpleName());}else{throw new CanNotHandleRequestException();}}}
?

SaveHandler?处理 保存请求(SaveRequest?

?

public class SaveHandler implements Handler{public void handleRequest(Request request) throws CanNotHandleRequestException{if(request instanceof SaveRequest){System.out.println("SaveHandler handle "+request.getClass().getSimpleName());}else{throw new CanNotHandleRequestException();}}}

?

4,客户端 Client

?

public class Client {public static void main(String[] args) throws CanNotHandleRequestException{HandlerContainer Container1 = new HandlerContainer();Container1.add(new HelpHandler());HandlerContainer Container2 = new HandlerContainer();Container2.add(new PrintHandler());Container2.add(new SaveHandler());Container1.add(Container2);Container1.handleRequest(new HelpRequest());Container1.handleRequest(new PrintRequest());Container1.handleRequest(new SaveRequest());}}
?

运行Client 类,输出如下

?

HelpHandler handle HelpRequest
PrintHandler handle PrintRequest
SaveHandler handle SaveRequest

?

?

?

public class PrintHandler implements Handler{ public void handleRequest(Request request) throws CanNotHandleRequestException{ if(request instanceof PrintRequest){ System.out.println("PrintHandler handle "+request.getClass().getSimpleName()); }else{ throw new CanNotHandleRequestException(); } } }

根据代码判断,如果request是PrintRequest的实例,则处理,否则抛出CanNotHandleRequestException异常表示我这个handler不能处理这个request,你还是找别人去吧。但是,如果哪天后来谁在实现某个Handler的时候,忘记了抛出CanNotHandleRequestException异常了呢,你又没强制我抛出CanNotHandleRequestException异常,仅仅是声明了CanNotHandleRequestException,我可以不抛出的,对吧。 那么,问题来了,按照基类的代码逻辑,不抛出CanNotHandleRequestException异常,则表示我这个handler可以处理这个request,但实际上却不是,我这个handler不能处理这个request,但也没有抛出CanNotHandleRequestException异常,基类却认为已经处理了,break了。
#HandlerContainer 中        public void handleRequest(Request request) throws CanNotHandleRequestException{           int length = this.handlers.size();           for(int i = 0 ; i < length ; i++){               Handler handler = handlers.get(i);               try {                   handler.handleRequest(request);                   [color=darkred][b]break;   [/b][/color]            } catch (CanNotHandleRequestException e) {                   /*                   * 如果处理器容器里的所有处理器都不能处理该请求,                   * 则由容器抛出 CanNotHandleRequestException 异常。                   */                  if(i == length-1) throw e;               }           }       }    


所以,个人认为,这里使用异常,有点画蛇添足。 其实你这里的目的是为了解耦(handler之间),这里的基类和http://www.iteye.com/topic/411182?page=1这里实现的第二种基类合并一起即可。

如:
 public void handleRequest(Request request) throws CanNotHandleRequestException{           int length = this.handlers.size();           for(int i = 0 ; i < length ; i++){               Handler handler = handlers.get(i);                              if(canHandleRequest(request)                           { //如果能处理这个request,则处理,并返回                              handler.handleRequest(request);                                 break;                           }                 }           }       }   


对于这种方式,即使handlerRequest方法有返回值,也可以处理,只需要在上面的代码中,改为return而不是break即可:
if(canHandleRequest(request)                           { //如果能处理这个request,则处理,并返回                                    return handler.handleRequest(request);                              }



btw:javaeye的code编辑方式真不是很好用 20 楼 jenlp520 2009-11-14   sky3380 写道楼主为何不用返回值来判断请求是否被处理?用抛出异常的方式感觉有些不妥

跟mina的ProtocolCodecFilter一样 用抛异常来终止 21 楼 chendw_hz 2009-12-18   改进后的模式效率应该不高,每次发送请求都要遍历处理容器容器中所有处理器,而原来的模式只要判断是否有该处理器就可以,如果有就处理,如果没有就不处理。
而且并发的时候,有可能两个不同处理会处理同一个请求。就是说有可能其中一个处理器得不到处理。 22 楼 chendw_hz 2009-12-18   如果同时存在两个相同处理器怎么办,就是说处理器还有可能引用两个完全相同的处理器。应该set更好。

热点排行