责任链模式介绍
责任链模式(Chain ofResponsibility)的目标是使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
在处理用户的请求时可能要根据不同的情况对请求添加不同的处理逻辑,在这时候就可以利用责任链进行设计。当需要添加一个处理逻辑时可以很方便的添加一个处理的节点。
职责链可以是一条直线、一个环或者一个树形结构,最常见的职责链是直线型,即沿着一条单向的链来传递请求。
链上的每一个对象都是请求处理者,职责链模式可以将请求的处理者组织成一条链,并使请求沿着链传递,由链上的处理者对请求进行相应的处理,客户端无须关心请求的处理细节以及请求的传递,只需将请求发送到链上即可,将请求的发送者和请求的处理者解耦。
角色包含
职责链模式包含如下角色:
Handler: 抽象处理者:定义出一个处理请求的接口。如果需要,接口可以定义出一个方法,以设定和返回对下家的引用。这个角色通常由一个抽象类或接口实现。
ConcreteHandler: 具体处理者:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可 以访问下家。
Client: 客户端
实例
下面我们通过具体的例子来分析说明如何使用职责链模式:
审批假条
某OA系统需要提供一个假条审批的模块,如果员工请假天数小于等于3天,TeamLeader可以审批该假条;如果员工请假天数大于3天,小于等于10天,ProjectLeader可以审 批;如果员工请假天数大于等于10天,小于等于30天,HR可以审批。大于30天无法审批!
1, 定义抽象处理者
public abstract class Handler {
public Handler handler=null;
public Handler getHandler() {
return handler;
}
public void setHandler(Handler handler) {
this.handler = handler;
}
public abstract void handleRequest(int day);
}
2, 定义具体处理者
TeamLeader:
public class TeamLeader extends Handler {
/*
* (non-Javadoc)
*
* @see com.ghy.zrl.handler.Handler#handleRequest()
*/
@Override
public void handleRequest(int day) {
if (day <= 3) {
System.out.println("TeamLeader批准");
} else {
System.out.println("请假天数超出TeamLeader权限,请找ProjectLeader请示");
if(getHandler() != null)
{
getHandler().handleRequest(day);
}
}
}
}
ProjectLeader:
public class ProjectLeader extends Handler {
/* (non-Javadoc)
* @see com.ghy.zrl.handler.Handler#handleRequest(int)
*/
@Override
public void handleRequest(int day) {
if (day <= 10) {
System.out.println("ProjectLeader批准");
} else {
System.out.println("请假天数超出ProjectLeader权限,请找HR请示");
if(getHandler() != null)
{
getHandler().handleRequest(day);
}
}
}
}
HR:
public class HR extends Handler {
/* (non-Javadoc)
* @see com.ghy.zrl.handler.Handler#handleRequest(int)
*/
@Override
public void handleRequest(int day) {
if (day <= 30) {
System.out.println("HR批准");
} else {
System.out.println("请假天数超出HR权限,请找联系公司高层!");
if(getHandler() != null)
{
getHandler().handleRequest(day);
}
}
}
}
3, 客户端调用
public class Client {
public static void main(String[] args) {
//组装责任链
Handler teamLeader=new TeamLeader();
Handler projectLeader=new ProjectLeader();
Handler hr=new HR();
teamLeader.setHandler(projectLeader);
projectLeader.setHandler(hr);
teamLeader.handleRequest(15);
}
}
实例源码下载
责任链模式优缺点
优点:
降低耦合度
可简化对象的相互连接
增强给对象指派职责的灵活性
增加新的请求处理类很方便
缺点:
不能保证请求一定被接收。
系统性能将受到一定影响,而且在进行代码调试时不太方便;可能会造成循环调用。
适用环境
有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。
在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
可动态指定一组对象处理请求。