《GOF设计模式》学习笔记--职责链Chain Of Responsibility

 
一、官方描述:
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
 
二、我的描述
 
1、一个简单例子:
记得在上初中的时候,有一个老师非常的特别,他有一个与众不同的习惯,就是同学们的作业是边看边发,他看完一本,点评两句,然后就把本子扔给前排的同学,继续看下一本,前排的同学再把本子往后传,只到传给本子的主人。
现在发现这其实是一个职责链(Chain Of Responsibility)模式的很好的例子,它解除了老师和同学之间的具体关联关系, 老师不需要与本子所属的那个同学直接联系,而是只把本子发给前排的同学,就可以假定已经发给了相应的同学,在同学传递本子的时候,检查本子是不是自己的,如果不是,就传递给下一位。
对象结构图如下:
 
2、职责链中的对象关系:
1) 对等的对象、位置无关;
2) 普化的对象关系,从特殊到一般,位置相关。
       老师把本子传给同学,同学根据本子是不是自己的来进行处理,如果是自己的便留下,否则继续往下传。在这里链中的对象(同学)是对等的,所以这个链是对象无关的,即链中的对象(同学)可以互换位置,而不影响处理结果。
       在职责链的使用中,链中的对象有时具有层次关系,比如GOF《设计模式》中图形用户界面上的帮助,打印窗口的按钮帮助包含于窗口帮助,窗口帮助又包含于应用帮助。
 
 
3、职责链中的对象类型:
1) 同一类型的对象;
2) 不同类型的对象;
在上面简单例子中, 职责链中的对象(同学),都是同一类( Student )的实例,每个同学根据本子的姓名,来决定是接收或是传递给下一个同学。
在职责链模式的运用中, 职责链中的对象也可以是不同类型的实例,比如我们构建一个模拟雇用者到人才市场雇用工人劳作的系统,人才市场里的工人包括各种类型,如电工、煤气工、水工等等。
在现实生活中我们有一件事情要找专业的工作人员来做,需要到市场上(当然现在可以直接打电话)找有相应技能的技工,这时我们要根据事情的性质来明确找哪一种技工,并与其联系。但是如果我们要构建一个模拟这一过程的软件系统,我们就可以用职责链模式来解欧雇用者和技工的关系,把技工对象连成一条链,并沿着这条链传递“事情”对象,直到有一个技工可以执行该件“事情”,否则技工对象把这一“事情”对象传给下一个技工对象。类结构及对象结构图如下所示:
类结构图:
 
对象结构图:
 
 
4、职责链的效果:
       在上面通过用职责链模式来改造现实中的雇佣者和技工之间的关系,带来了两方面的效果:
1) 通过解耦,简化了雇用者的操作,雇用者只需把事情抛给一个技工即可,技工或者自己执行或者传递给下一个技工;
2) 人才市场可以方便对技工对象链进行管理,增加或替换删除一些技工,以便完善人才市场,为顾客(雇用者)提供更好的服务;并且这种管理(增加/替换/删除)对顾客是透明的。
 
5、Java代码示例:
下面代码演示了简单例子中老师给同学发本子的过程,这里的链中对象都属于同一类Student的不同实例,对于链中的对象是不同类型的情况,可以参考GOF《设计模式》中的代码或考虑上面雇佣技工系统的实现。
本部分代码示例包括三个类:Book、Student、和Client
 
代码清单如下:
类Book,本子类,包括本子的主人名字属性
 
package  qinysong.pattern.chainOfResponsibility;

public   class  Book  {

  
private String studentName;

  
public Book(String studentName){
    
this.studentName = studentName;
  }


  
public String getStudentName(){
    
return studentName;
  }

}

 
类Student,学生类,包括姓名和下一个同学属性
 
package  qinysong.pattern.chainOfResponsibility;

public   class  Student  {

  
private String name;
  
private Student nextStudent;

  
public Student(String name, Student nextStudent){
    
this.name = name;
    
this.nextStudent = nextStudent;
  }


  
public void acceptBook(Book book){
    
if (book.getStudentName().equals(name)){
      System.out.println(
"Student(" + name + ").acceptBook 这是我的本子,我收下了,呵呵!");
    }
 else {
      
if (nextStudent != null{
        System.out.println(
"Student(" + name + ").acceptBook 这不是我的本子,我传给下一个同学");
        nextStudent.acceptBook(book);
      }
 else {
        System.out.println(
"Student(" + name + ").acceptBook 这不是我的本子,而且我是最后一个同学了,所以本子没人要了!");
      }

    }

  }

}

 
类Client,测试类,包括维护学生链,和向学生链传递本子两部分
 
package  qinysong.pattern.chainOfResponsibility;

// 扮演两个角色:1)上下文环境的管理者,构建同学链、2)老师,把本子传给同学链
public   class  Client  {
  
public static void main(String[] args){
    System.out.println(
"Client.main begin ......");
    
//构造同学链
    Student zhangsan = new Student("zhangsan"null);
    Student lisi 
= new Student("lisi", zhangsan);
    Student wangwu 
= new Student("wangwu", lisi);

    
//模拟老师,把李四的本子发出去
    wangwu.acceptBook(new Book("lisi"));
    
//模拟老师,发一个别的班的同学的本子
    wangwu.acceptBook(new Book("xxx"));
    System.out.println(
"Client.main end   ......");
  }

}

 
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值