设计模式中的责任链模式解析

这篇主要是在看Tomcat源码的时候,遇到了责任链模式相关的东西,做一下简单记录,可以和Tomcat源码中责任链的应用对比学习下,会更有效果。

责任链模式的定义

责任链模式(Chain of Responsibility)是一种对象的行为模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。
《JAVA与模式》-阎宏

责任链模式的结构

责任链模式总共存在两个角色,抽象处理者(Handler)和具体处理者(ConcreteHandler)。

抽象处理者,定义处理请求的接口,通常也会有包含下一个和上一个处理者的方法,抽象处理者一般是一个接口或者抽象类。

具体处理者,是对抽象处理者的实现,不同的实现。当前如果能处理请求,就处理,如果不能处理请求就交给下家处理。

责任链模式的举例

Handler:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package me.cxis.test.gof.chainofresponsibility;

/**
* Created by cheng.xi on 2017-05-05 17:46.
*/
public abstract class Handler {
protected Handler successor;

public abstract void handleRequest(String condition);

public Handler getSuccessor() {
return successor;
}

public void setSuccessor(Handler successor) {
this.successor = successor;
}
}

ConcreteHandler1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package me.cxis.test.gof.chainofresponsibility;

/**
* Created by cheng.xi on 2017-05-05 17:49.
*/
public class ConcreteHandler1 extends Handler {
@Override
public void handleRequest(String condition) {
if(condition.equals("1")){
System.out.println("ConcreteHandler1处理");
return;
}else {
System.out.println("ConcreteHandler1不处理,由其他的Handler处理");
getSuccessor().handleRequest(condition);
}
}
}

ConcreteHandler2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package me.cxis.test.gof.chainofresponsibility;

/**
* Created by cheng.xi on 2017-05-05 17:49.
*/
public class ConcreteHandler2 extends Handler {
@Override
public void handleRequest(String condition) {
if(condition.equals("2")){
System.out.println("ConcreteHandler2处理");
return;
}else {
System.out.println("ConcreteHandler2不处理,由其他的Handler处理");
getSuccessor().handleRequest(condition);
}
}
}

ConcreteHandlerX:

1
2
3
4
5
6
7
8
9
10
11
12
package me.cxis.test.gof.chainofresponsibility;

/**
* Created by cheng.xi on 2017-05-05 17:49.
*/
public class ConcreteHandlerX extends Handler {
@Override
public void handleRequest(String condition) {
//一般是最后一个处理者
System.out.println("ConcreteHandlerX处理");
}
}

Client:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package me.cxis.test.gof.chainofresponsibility;

/**
* Created by cheng.xi on 2017-05-05 17:53.
*/
public class Client {
public static void main(String[] args) {
Handler handler1 = new ConcreteHandler1();
Handler handler2 = new ConcreteHandler2();
Handler handlerX = new ConcreteHandlerX();

handler1.setSuccessor(handler2);
handler2.setSuccessor(handlerX);

handler1.handleRequest("2");
}
}

责任链模式的优点

当然上面的例子我们可以直接在Client中写if-else,不过这样耦合度就太高了,而且如果顺序发生变化会很难弄,而责任链模式可以解耦,将发送者和接受者分开。

责任链模式的缺点

责任链可能很长,即便某一个点不处理请求,也需要经过这个点,这样会有性能问题。

责任链模式的应用场景

  • Servlet中的过滤器
  • Tomcat中的Filter
  • Tomcat中容器的设置
坚持原创技术分享,您的支持将鼓励我继续创作!
Fork me on GitHub