职责链模式

此文章已经在iteye发表过:http://jason61719.iteye.com/blog/1025463

 

装饰模式实际上很像一条单链表,每次装饰就是增加一个结点,增加一个结点以后这个对象就有了新的功能。设计模式中还有一种类似单链表的模式,职责链模式。

 

假设一个情景:学生可以申请请假,这个申请交由负责的辅导员,辅导员能批3 天以内典型的假期。如果不满足条件就交给年级主任,年级主任能够批1 个星期以内的假期,如果超过1 个星期的就得交给学院批,由学院来决定行不行。如图:

假设现在让你在一个教学系统中设计上面这个业务,应该如何设计好?

这样子,让学生自己判断,3 天的找辅导员,7 天的找主任……

那么可以用代码这样子实现:

这是辅导员类:

 

接下来的是主任类和学院类,跟上面辅导员类差不多:

 

接下来是学生,学生先判断应该问谁,然后发出请求:

场景:

运行一下,如下:

 


这样子设计好吗?不好,代码不健壮。

如果我现在要申请2 天的事假,按照判断我应该交给Teacher ,但是Teacher 说他处理不了这样的事情,那就结束了吗?事实上就应该转交给Chairman 处理。这时候会想,我们把sendRequest() 方法加多一层判断不就行了吗?这就耦合了,另一方面,如果每个负责人的职责经常变化,那是不是得经常修改sendRequest() 和相应的负责人的源代码?单一职责设计原则约定好只能有一个原因可以引起类的变化,这就不符合单一职责原则,而且也不符合开闭原则。其次在一个方法中有大量的逻辑判断也显得代码臃肿,可读性差。

这里介绍职责链设计模式。作为一种行为模式,它是为了使多个对象都有机会处理请求,尽可能的避免请求者和处理者之间的耦合,而是让请求者只负责发送,处理者接受以后处理请求,如果不能处理就交给下一个处理者,直到有一个对象可以处理它。这时候处理者形成一条链表用于传递请求。

按照职责链模式我们修改学生发送请求的流程图。

改成这样以后,1 )首先学生只要把请求发给辅导员就行了,辅导员如果处理不了就交给上一级,这时候学生类知道的东西很少,这就符合迪米特设计原则了。2 )要增加多逻辑关系很容易,只要修改对应的负责人就行,不用修改发送请求的学生类,而且,要加入多一个负责人也很简单,只要扩展多一个类就行,耦合变低,相对来说更符合开闭原则。3 )将各自的职责分开,学生不用处理关于负责人逻辑判断的东西,符合单一职责的原则。之后负责人方面要怎么修改,都不用修改学生类。

下面是重新修改的源代码:

处理者的抽象类:

修改3 个负责人类,如下:

以下是学生类,方法名未变,内部组装职责链过程在实际应用中可以优化:

 

下面是场景,跟之前的一模一样:

运行结果如下:


下面给出UML 设计图:

说明: E:/User/Desktop/【2011年4月30日】职责链.jpg

抽象处理者(Handler) 角色:定义出一个处理请求的接口。如果需要,接口可以定义出一个方法,以设定和返回对下家的引用。这个角色通常由一个抽象类或接口实现。

具体处理者(ConcreteHandler) 角色:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值