如果你在公司遇到了什么问题,求助于部门经理,如果在他职责范围之内,他会帮你解决;但是如果不在部门经理职责范围内,他会递交给总经理,同样的,如果总经理能解决,他会解决,如果解决不了他会往上提交。其实这也是责任链模式的体现。通过责任链模式,你可以为某个请求创建一个对象链。每个对象依序检查次请求,并对其进行处理,或者将它传给链中的下一个对象。上述讲的,向上级提交问题也是责任链形式,比如将部门经理、总经理等作为对象,员工的问题就是请求,这些对象依次检查该请求,能解决的则解决,如果不能解决,则链的下个对象传递。
1.适用性与优缺点
1.适用性
a.有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定
b.你想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
c.可处理一个请求的对象集合应被动态指定。
2.优点
a.将请求的发送者和接收者解耦。
b.可以简化对象,不知链结构。
c.通过改变链内的成员或调动它们的次序,允许动态地增加或者删除责任。
3.缺点
a.并不保证请求一定会执行,没有对象处理,则会落在链尾。
b.可能不容易观察运行时的特征,不易排错。
2.示例讲解
接下来,我们讲解一个公司人事的例子,假设有请假、加薪、离职等请求,那么请求对象有项目经理、项目组长和人事等,不同对象对应不同请求,但是每个请求都是通过责任链来处理,从链头到链尾依次处理。
首先定义请求接口
package request;
public interface Request {
}
然后是具体请求实现
package request;
public class AddMoneyRequest implements Request {
}
package request;
public class DimissionRequest implements Request {
}
package request;
public class LeaveRequest implements Request {
}
接着是处理请求的接口
package handler;
import request.*;
public interface RequestHandle {
public void hanleRequest(Request request);
}
处理请求类的实现
package handler;
import request.*;
public class HRRequestHandle implements RequestHandle {
@Override
public void hanleRequest(Request request) {
// TODO Auto-generated method stub
if(request instanceof DimissionRequest)
{
System.out.println("要离职,人事审批!");
}
System.out.println("请求完毕");
}
}
package handler;
import request.*;
public class PMRequestHandle implements RequestHandle {
RequestHandle rh;
public PMRequestHandle(RequestHandle rh)
{
this.rh=rh;
}
@Override
public void hanleRequest(Request request) {
// TODO Auto-generated method stub
if(request instanceof AddMoneyRequest)
{
System.out.println("要加薪,项目经理审批!");
}
else
{
rh.hanleRequest(request);
}
}
}
package handler;
import request.*;
public class TLRequestHandle implements RequestHandle {
RequestHandle rh;
public TLRequestHandle(RequestHandle rh)
{
this.rh=rh;
}
@Override
public void hanleRequest(Request request) {
// TODO Auto-generated method stub
if(request instanceof LeaveRequest)
{
System.out.println("要请假,项目组长审批!");
}
else
{
rh.hanleRequest(request);
}
}
}
上面三个类中只有第一个类没有把对象递交给下一个的处理,所以一定是链尾,其它两个的顺序可以改变,而且三个类统一接口,就是为了便于依次检查此请求。
接着是测试程序
package handler;
import request.*;
public class Test {
public static void main(String[] args)
{
RequestHandle hr=new HRRequestHandle();
RequestHandle pm=new PMRequestHandle(hr);
RequestHandle tl=new TLRequestHandle(pm);
Request request=new DimissionRequest();
pm.hanleRequest(request);
System.out.println("========");
request=new AddMoneyRequest();
tl.hanleRequest(request);
System.out.println("========");
request=new DimissionRequest();
pm.hanleRequest(request);
}
}
运行程序得到如下结果:
要离职,人事审批!
请求完毕
========
要加薪,项目经理审批!
========
要离职,人事审批!
请求完毕
根据以上例子的先把项目组长对象作为链头,即第一个进行处理请求的对象,接着是项目经理,最后才是人事。每当有一个请求,都是按照这个对象链的顺序来进行处理,如果当前对象能够处理则处理,不能处理则传递给下一个对象,直到链尾。