CoR 模式 (第一种)
CoR(Chain of Responsibility) 即职责链设计模式:使多个对象都有机会处理请求(Request),从而避免请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理他为止。
职责链设计模式 大概有三个角色:
(1)请求(Request):封装请求信息
(2)处理器(Handler):处理请求(Request),一个具体处理器一般只处理一种请 求,如果它不能处理传递过来的请求,那么它就把该请求传递给职责链中的下一个处理器(后继处理器 successor)。
(3)客户端(Client):发送请求
定义不再多说,直接看实现。下面是一个传统的CoR实现:
1,代表抽象请求的接口(Request)
public interface Request{
//......
}
2,实现Request接口的实现类,HelpRequest,PrintRequest,SaveRequest
假设有一个文本编辑器,用户界面上有三个按钮 Help,Print 和 Save
HelpRequest 代表 当用户点击 Help 按钮时产生的 帮助请求,
PrintRequest 代表 当用户点击 Print 按钮时产生的 打印请求,
SaveRequest 代表当用户点击 Save 按钮时产生的 保存请求。
//帮助请求
public class HelpRequest implements Request{
//......
}
//打印请求
public class PrintRequest implements Request{
//......
}
//保存请求
public class SaveRequest implements Request{
//......
}
3,代表抽象处理器的接口Handler:
public interface Handler{
void handleRequest(Request request);
}
4,实现处理器接口的实现类 HelpHandler,PrintHandler,SaveHandler:
HelpHandler 处理 帮助请求(HelpRequest)
public class HelpHandler implements Handler{
//后继处理器
private Handler successor;
public HelpHandler(Handler successor){this.successor = successor;}
public void handleRequest(Request request) {
if(request instanceof HelpRequest){
System.out.println("HelpHandler handle " +request.getClass().getSimpleName());
// handle request
}else{
System.out.println("PrintHandler can't handle "+request.getClass().getSimpleName());
if(successor != null)
successor.handleRequest(request);
}
}
}
PrintHandler 处理 打印请求(PrintRequest)
public class PrintHandler implements Handler{
//后继处理器
private Handler successor;
public PrintHandler(Handler successor){this.successor = successor;}
public void handleRequest(Request request) {
if(request instanceof PrintRequest){
System.out.println("PrintHandler handle "+request.getClass().getSimpleName());
// handle request
}else{
System.out.println("PrintHandler can't handle "+request.getClass().getSimpleName());
if(successor != null)
successor.handleRequest(request);
}
}
}
SaveHandler处理 保存请求(SaveRequest)
public class SaveHandler implements Handler{
//后继处理器
private Handler successor;
public SaveHandler(Handler successor){this.successor = successor;}
public void handleRequest(Request request) {
if(request instanceof SaveRequest){
System.out.println("SaveHandler handle "+request.getClass().getSimpleName());
// handle request
}else{
System.out.println("SaveHandler can't handle "+request.getClass().getSimpleName());
if(successor != null)
successor.handleRequest(request);
}
}
}
5,客户端 Client 类
public class Client{
public static void main(String[] args){
Handler handler1 = new HelpHandler(null);
Handler handler2 = new PrintHandler(handler1);
Handler handler3 = new SaveHandler(handler2);
handler3.handleRequest(new HelpRequest());
handler3.handleRequest(new PrintRequest());
handler3.handleRequest(new SaveRequest());
}
}
运行 Client 类 输出如下:
SaveHandler can't handle HelpRequest
PrintHandler can't handle HelpRequest
HelpHandler handle HelpRequest
SaveHandler can't handle PrintRequest
PrintHandler handle PrintRequest
SaveHandler handle SaveRequest
-----------------------------------------------------
用抽象类也可以,不过要把 handleRequest 中
(1)这个处理器是否能处理这个请求
和
(2)处理相应的请求
这两个功能分离出来,定义成抽象方法供子类(具体处理器)实现
public abstract class AbstractHandler implements Handler {
protected Handler successor;
public AbstractHandler(Handler successor) {
this.successor = successor;
}
//定义为final,不能被子类继承
public final void handleRequest(Request request) {
if (canHandleRequest(request)) {
handleRequestMyself(request);
} else {
if (successor != null)
successor.handleRequest(request);
}
}
//这个处理器能否处理整个请求
protected abstract boolean canHandleRequest(Request request);
//处理相应的请求
protected abstract void handleRequestMyself(Request request);
}
CoR 模式 (第二种)
CoR(Chain of Responsibility) 职责链设计模式
讨论了传统的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