注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

东东的博客

江南烟雨,同大家一起分享

 
 
 

日志

 
 

设计模式读书笔记之职责链模式(chain of responsibility)  

2010-07-13 20:07:45|  分类: 设计模式相关 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

职责链模式:当一个请求有可能被多个对象处理,则将这些对象连成一条链,并沿着这条链传递请求,直到该请求被处理为止。

单看上图, 你肯定看不出职责链模式的特征, 先举一个例子来说明一下. 比如一个员工想加工资, 他首先会告知team leader, 如果在team leader授权范围之内,则他可以办到, 否则,就要请求上级来处理,最后直到老板, 于是很容易写出这样的代码来:


view plaincopy to clipboardprint?
public class Employee {  
    private TeamLeader tl;  
    private DeptManager deptMgr;  
    private GeneralManager gm;  
    private Boss boss;  
    //some other properties  
    public void addSalary(int x){  
        if(x<=100){  
            tl.addSalary(this, x);  
        }  
        else if(x<=500){  
            deptMgr.addSalary(this, x);  
        }  
        else if(x<=800){  
            gm.addSalary(this, x);  
        }  
        else{  
            boss.addSalary(this, x);  
        }  
    }  
    // some other methods  
}  

这个代码中的if else带来了坏味道, 同时, Employee必须知道他的每一个上司,并使Employee和每一个处理者(他的上司)耦合在一起. 其实一个Employee一般来说只需要和他的直接上司打交道就可以了. 就如下时序图所示.

把Employee的上司连成一条链, 即team leader持有他的上司部门经理, 部门经理持有他的上司总经理, 总经理持有他的上司老板. 则Employee只需要知道team leader即可.

加薪代码:


view plaincopy to clipboardprint?
//  
public interface Supervisor {  
    public void addSalary(Employee e, int added);  
}  
  
///////////////////  
public class Employee {  
    public String name;  
    private Supervisor supervisor;  
    public Employee(String name){  
        this.name = name;  
    }  
    public void setSupervisor(Supervisor supervisor) {  
        this.supervisor = supervisor;  
    }  
    public void addSalary(int added){  
        if(supervisor!=null){  
            supervisor.addSalary(this, added);  
        }  
    }  
      
}  
///////////////////  
public class TeamLeader implements Supervisor{  
    private Supervisor successor;  
    public TeamLeader(Supervisor s){  
        this.successor = s;  
    }  
    public void addSalary(Employee e, int added) {  
        if(added<100){  
            System.out.println("Team Leader: " + e.name + " want to add "   
                    + added + " salary, I can process it, done!");  
        }  
        else if(successor!=null){  
            System.out.println("Team Leader: " + e.name + " want to add "   
                    + added + " salary, I can't process it, but my supervisor can do!");  
            successor.addSalary(e, added);  
        }  
    }  
}  
///////////////////  
public class DeptManager implements Supervisor{  
    private Supervisor successor;  
    public DeptManager(Supervisor s){  
        this.successor = s;  
    }  
    public void addSalary(Employee e, int added) {  
        if(added<500){  
            System.out.println("Dept Manager: " + e.name + " want to add "   
                    + added + " salary, I can process it, done!");  
        }  
        else if(successor!=null){  
            System.out.println("Dept Manager: " + e.name + " want to add "   
                    + added + " salary, I can't process it, but my supervisor can do!");  
            successor.addSalary(e, added);  
        }  
    }  
}  
///////////////////////  
public class GeneralManager implements Supervisor{  
    private Supervisor successor;  
    public GeneralManager(Supervisor s){  
        this.successor = s;  
    }  
    public void addSalary(Employee e, int added) {  
        if(added<800){  
            System.out.println("General Manager: " + e.name + " want to add "   
                    + added + " salary, I can process it, done!");  
        }  
        else if(successor!=null){  
            System.out.println("General Manager: " + e.name + " want to add "   
                    + added + " salary, I can't process it, but my supervisor can do!");  
            successor.addSalary(e, added);  
        }  
    }  
}  
//////////////////  
public class Boss implements Supervisor{  
    public Boss(){}  
    public void addSalary(Employee e, int added) {  
        //boss具有最终处理权限, 但是他打官腔  
        System.out.println("Boss: I will process it soon.");  
    }  
}  
/////////////////////////////  
//测试用例  
public class Test {  
    public static void main(String[] args) {  
        Employee e = new Employee("Jack");  
        Boss b = new Boss();  
        GeneralManager gm = new GeneralManager(b);  
        DeptManager dm = new DeptManager(gm);  
        TeamLeader tl = new TeamLeader(dm);  
        e.setSupervisor(tl);  
        e.addSalary(1200);  
    }  
}  
/////////////////////////////  
//输出  
//Team Leader: Jack want to add 1200 salary, I can't process it, but my supervisor can do!  
//Dept Manager: Jack want to add 1200 salary, I can't process it, but my supervisor can do!  
//General Manager: Jack want to add 1200 salary, I can't process it, but my supervisor can do!  
//Boss: I will process it soon.  

上面的代码有两个优点:

1 Employee不再依赖于具体的上司,转而依赖于抽象, 而且不必知道所有的上司;

2 如果新增了处理者, 只需要更改客户端代码, 即重新构造责任链就可以了.

基础代码:


view plaincopy to clipboardprint?
package designpattern.chainofresponsibility;  
  
public abstract class Handler {  
    //注意修饰符为protected,因为子类要访问他  
    protected Handler successor;  
      
    public void setSuccessor(Handler successor) {  
        this.successor = successor;  
    }  
      
    public abstract void handleRequest(int request);  
}  
//  
package designpattern.chainofresponsibility;  
  
public class ConcreteHandler1 extends Handler {  
    public void handleRequest(int request) {  
        if(request>=0&&request<10){  
            System.out.println("request handled by ConcreteHandler1");  
            return;  
        }  
        if(successor!=null){  
            System.out.println("ConcreteHandler1 can't handle this request, dispatch to next.");  
            successor.handleRequest(request);  
        }  
    }  
}  
//  
package designpattern.chainofresponsibility;  
  
public class ConcreteHandler2 extends Handler {  
    public void handleRequest(int request) {  
        if(request>=10&&request<20){  
            System.out.println("request handled by ConcreteHandler2");  
            return;  
        }  
        if(successor!=null){  
            System.out.println("ConcreteHandler2 can't handle this request, dispatch to next.");  
            successor.handleRequest(request);  
        }  
    }  
}  
//  
package designpattern.chainofresponsibility;  
  
public class ConcreteHandler3 extends Handler {  
    public void handleRequest(int request) {  
        if(request>=20&&request<30){  
            System.out.println("request handled by ConcreteHandler3");  
            return;  
        }  
        if(successor!=null){  
            System.out.println("ConcreteHandler3 can't handle this request, dispatch to next.");  
            successor.handleRequest(request);  
        }  
    }  
}  
//  
package designpattern.chainofresponsibility;  
  
public class ConcreteHandler4 extends Handler {  
    public void handleRequest(int request) {  
        if(request>=30){  
            System.out.println("request handled by ConcreteHandler3");  
            return;  
        }  
    }  
}  
//客户端测试用例  
package designpattern.chainofresponsibility;  
  
public class Client {  
    public static void main(String[] args){  
        Handler handler1 = new ConcreteHandler1();  
        Handler handler2 = new ConcreteHandler2();  
        Handler handler3 = new ConcreteHandler3();  
        Handler handler4 = new ConcreteHandler4();  
        handler1.setSuccessor(handler2);  
        handler2.setSuccessor(handler3);  
        handler3.setSuccessor(handler4);  
        handler1.handleRequest(60);  
    }  
}  

责任链模式的关键点在于把请求的处理者连成一条链,一个处理者可以处理当前请求,也有权决定是否沿着链朝上传递请求.

优点:

1 可以简化对象之间的连接,他们只需要知道一个后继者就行了;

2 可以很方便的增加或修改处理者。

注意:

一个请求可以传递到末端都得不到处理,因此需要考虑全面。

经典案例:

jdk中我真的没有找到合适的例子,网上说Java 1.0版本中的AWT库采用责任链模式和命令模式来处理GUI的事件,我觉得有兴趣你可以看一下源码.DHTML中的事件处理机制可以看作职责链模式,这 种机制又叫事件冒泡(Event Bubbling)机制, 当页面中的一个dom节点捕获一个事件(比如鼠标双击), 当前节点的处理函数可以处理改事件,然后也可以决定是否向上冒泡让父元素继续处理这个事件.浏览器的事件处理机制也是这样的。

如果你想到了j2ee中的Filter,或者spring中的Interceptor和ExecutionChain, 那你就错了. 因为就实现方法上看, Filter和Interceptor以及ExecutionChain都不是职责链模式.


转自:http://blog.csdn.net/sunxing007/archive/2010/04/05/5452799.aspx

  评论这张
 
阅读(523)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017