职责链模式
又称责任链模式(Chain of Responsibility),是指为了避免请求的发送者和接收者之间的耦合关系,使多个接收对象都有机会处理请求。将这些对象形成一条链,沿着这条链传递请求,直到有一个对象处理为止。
通俗一点说:当客户提交一个请求时,从第一个对象开始,链中收到请求的对象要么亲自处理它,要么传递给下一个对象,提交请求的对象并不知道谁会处理它。职责链中也可能没有一个对象处理请求。
职责链模式结构
1.抽象处理者角色(Handler):定义一个处理请求的接口,如果需要,接口可以定义出一个方法返回对下家的引用。
2.具体处理者角色(ConcreteHandler):具体处理者接到请求后,可以选择处理掉或者传递给下家。
两种责任链模式
纯和不纯。
纯的责任链模式要求一个具体的处理者对象只能在两个行为里面选择一个:一是承担责任,二是将责任推给下家。不允许出现某一个具体处理者对象处理请求后继续往下传的情况。
在一个纯的责任链模式里面,一个请求必须被某一个处理者对象所接受,在一个不纯的责任链模式里面,一个请求最终可以不被任何处理者对象接受。
纯的责任链模式很难找到。
public interface Level {
static final int LEVEL_01 = 1;
static final int LEVEL_02 = 2;
static final int LEVEL_03 = 3;
}
/**
* 抽详请求类
* @author 张家骏
*
*/
public abstract class AbstractRequest {
public abstract int getRequestLevel();
public abstract String getContent();
}
public class Request_01 extends AbstractRequest{
@Override
public String getContent() {
return "Request_01";
}
@Override
public int getRequestLevel() {
return Level.LEVEL_01;
}
}
public class Request_02 extends AbstractRequest{
@Override
public String getContent() {
return "Request_02";
}
@Override
public int getRequestLevel() {
return Level.LEVEL_02;
}
}
public class Request_03 extends AbstractRequest{
@Override
public String getContent() {
return "Request_03";
}
@Override
public int getRequestLevel() {
return Level.LEVEL_03;
}
}
/**
* 抽象处理者
* @author 张家骏
*
*/
public abstract class Handler {
protected Handler nextHandler;
abstract void handlerRequest(AbstractRequest request);
abstract int getHandlerLevel();
abstract void handler(AbstractRequest request);
public Handler getNextHandler() {
return nextHandler;
}
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
}
public class Handler_01 extends Handler{
@Override
void handlerRequest(AbstractRequest request) {
if (request.getRequestLevel() == getHandlerLevel()) {
handler(request);
} else {
if (nextHandler != null) {
System.out.println("Handler_01不能处理,交给下家处理");
this.nextHandler.handlerRequest(request);
} else {
System.out.println("没有任何对象能处理");
}
}
}
@Override
int getHandlerLevel() {
return Level.LEVEL_01;
}
@Override
void handler(AbstractRequest request) {
System.out.println("请求被Handler_01处理");
}
}
public class Handler_02 extends Handler {
@Override
int getHandlerLevel() {
return Level.LEVEL_02;
}
@Override
void handler(AbstractRequest request) {
System.out.println("请求被Handler_02处理");
}
@Override
void handlerRequest(AbstractRequest request) {
if (getHandlerLevel() == request.getRequestLevel()) {
handler(request);
} else {
if (nextHandler != null) {
System.out.println("Handler_02不能处理,交给下家处理");
this.nextHandler.handler(request);
} else {
System.out.println("没有任何对象能处理");
}
}
}
}
public class Handler_03 extends Handler {
@Override
int getHandlerLevel() {
return Level.LEVEL_03;
}
@Override
void handler(AbstractRequest request) {
System.out.println("请求被Handler_03处理");
}
@Override
void handlerRequest(AbstractRequest request) {
if (request.getRequestLevel() == getHandlerLevel()) {
handler(request);
} else {
if (nextHandler != null) {
System.out.println("Handler_02不能处理,交给下家");
nextHandler.handler(request);
} else {
System.out.println("没有任何对象能处理");
}
}
}
}
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
AbstractRequest request = new Request_03();
Handler handler1 = new Handler_01();
Handler handler2 = new Handler_02();
Handler handler3 = new Handler_03();
handler1.setNextHandler(handler2);
handler2.setNextHandler(handler3);
handler1.handlerRequest(request);
}
}
总结
责任链模式减低了请求的发送端和接收端之间的耦合,使多个对象都有机会处理这个请求。
在如下情况考虑使用责任链模式:
1.有多个对象可以处理一个请求,哪个对象处理该请求在运行时刻自动确定。
2.想在不明确指定接收者的情况下,通过对象中的一个提交一个请求。
3.可处理一个请求的对象集合应该被动态指定。
职责链模式使用一系列类试图处理一个请求,这些类是松散的耦合,唯一共同点是它们实现继承同样抽象角色、在它们之间传递请求,请求在它们之间像一个链条一样传下去。
优点:无法预知来自外界的请求属于哪种类型,每个类遇到不能处理的请求只要放弃就可以。
缺点:效率低,每个请求有可能遍历所有的对象到最后才可能完成;
扩展性差,职责链中一定要有一个统一的接口Handler。