论坛首页 Java企业应用论坛

CoR 模式(另一种)

浏览 8845 次
精华帖 (0) :: 良好帖 (12) :: 新手帖 (0) :: 隐藏帖 (5)
作者 正文
   发表时间:2009-06-18   最后修改:2009-06-18

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());
		}else
			throw 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

 

 

 

   发表时间:2009-06-19  
感觉有点像Composite模式。。
0 请登录后投票
   发表时间:2009-06-19  
visitor 写道
感觉有点像Composite模式。。


有点像,但意图不同,Composite侧重于 遍历所有 一个节点的所有子节点
不过 这种职责链模式 不是遍历所有节点,当有一个子节点能够处理请求的时候,
就不会遍历余下的子节点。
0 请登录后投票
   发表时间:2009-06-19  
引用

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

像这种关系貌似不能用耦合来定义,虽然持有后继引用,但实际上没有任何耦合关系,没有以依赖关系!!!
0 请登录后投票
   发表时间:2009-06-19  
kjj 写道
引用

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

像这种关系貌似不能用耦合来定义,虽然持有后继引用,但实际上没有任何耦合关系,没有以依赖关系!!!



处理器之间的耦合度。
(1)处理器持有后继处理器的引用,处理器之间为控制耦合。
(2)而由容器来管理处理器,处理器之间为非直接耦合。

非直接耦合:两个模块之间没有直接关系,它们之间的联系完全是通过主模块的控制和调用来实现的 。
控制耦合:如果一个模块通过传送开关、标志、名字等控制信息,明显地控制选择另一模块的功能,就是控制耦合。

 

控制耦合的耦合度 大于 非直接耦合

所以我说“让 每个处理器都持有后继处理器的引用,会增加处理器之间的耦合度.”

0 请登录后投票
   发表时间:2009-06-19  
好像比传统的COR实现要灵活。
支持一下--
0 请登录后投票
   发表时间:2009-06-21  
楼主为何不用返回值来判断请求是否被处理?用抛出异常的方式感觉有些不妥
0 请登录后投票
   发表时间:2009-06-21  
sky3380 写道
楼主为何不用返回值来判断请求是否被处理?用抛出异常的方式感觉有些不妥


恩 ,也可以,
不过要是 处理请求本身有返回值 的时候,那就不适用了。
比如 处理一个请求,返回一个应答。
0 请登录后投票
   发表时间:2009-06-21  
个人比较赞同研究一下《设计模式》。正如书中的提到的,这本书是面向对象程序设计的基础,

象楼主这样根据需要做一些改进,我觉的非常的好。



面向对象有两句话:

1.尽可能但又适当的抽象。

2.将变化的东西与不变的东西分开。

0 请登录后投票
   发表时间:2009-06-21  
这种模式有什么好处呢?
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics