设计模式系列:责任链模式

概念

责任链模式顾名思义,它是由一连串单一职责的对象构成链式结构。此结构一般为请求接受者做前置业务处理,主要目的是
为发送者和接收者进行解耦。其特点是,每个对象都只处理自己成处理的请求,如果处理不了,会把请求传给下一个接收者。以此类推。

实现

一个简单的日志记录链

类图

图片

代码

AbstractLogger

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package com.littlehui.design.responsebilitychain;

/**
* @Description TODO
* @ClassName AbstractLogger
* @Author littlehui
* @Date 2019/7/29 15:12
* @Version 1.0
**/
public abstract class AbstractLogger {

public static int INFO = 1;

public static int WARN = 2;

public static int ERROR = 3;

protected int level;

AbstractLogger nextLogger;

public void setNextLogger(AbstractLogger nextLogger) {
this.nextLogger = nextLogger;
}

public void logMessage(int level, String message){
if(this.level <= level){
write(message);
}
if(nextLogger !=null){
nextLogger.logMessage(level, message);
}
}

abstract protected void write(String message);
}

ErrorLogger

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.littlehui.design.responsebilitychain;

/**
* @Description TODO
* @ClassName ErrorLogger
* @Author littlehui
* @Date 2019/7/29 15:15
* @Version 1.0
**/
public class ErrorLogger extends AbstractLogger {

public ErrorLogger(int level){
this.level = level;
}

@Override
protected void write(String message) {
System.out.println("Error Console::Logger: " + message);
}
}

InfoLogger

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.littlehui.design.responsebilitychain;

/**
* @Description TODO
* @ClassName InfoLogger
* @Author littlehui
* @Date 2019/7/29 15:16
* @Version 1.0
**/
public class InfoLogger extends AbstractLogger {

public InfoLogger(int level){
this.level = level;
}

@Override
protected void write(String message) {
System.out.println("Error Console::Logger: " + message);
}
}

WarnLogger

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.littlehui.design.responsebilitychain;

/**
* @Description TODO
* @ClassName WarnLogger
* @Author littlehui
* @Date 2019/7/29 15:16
* @Version 1.0
**/
public class WarnLogger extends AbstractLogger {

public WarnLogger(int level){
this.level = level;
}

@Override
protected void write(String message) {
System.out.println("Error Console::Logger: " + message);
}
}

Demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

package com.littlehui.design.responsebilitychain;

/**
* @Description TODO
* @ClassName Demo
* @Author littlehui
* @Date 2019/7/29 15:18
* @Version 1.0
**/
public class Demo {

private static AbstractLogger getChainOfLoggers(){

AbstractLogger errorLogger = new ErrorLogger(AbstractLogger.ERROR);
AbstractLogger infoLogger = new InfoLogger(AbstractLogger.INFO);
AbstractLogger warnLogger = new WarnLogger(AbstractLogger.WARN);

errorLogger.setNextLogger(infoLogger);
infoLogger.setNextLogger(warnLogger);
return errorLogger;
}

public static void main(String[] args) {
AbstractLogger loggerChain = getChainOfLoggers();
loggerChain.logMessage(AbstractLogger.INFO, "This is an information.");
loggerChain.logMessage(AbstractLogger.WARN,
"This is a warn level information.");
loggerChain.logMessage(AbstractLogger.ERROR,
"This is an error information.");
}
}

执行结果:

1
2
3
4
5
6
7
8
9
10
11
/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/bin/java -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:65034,suspend=y,server=n -Dfile.encoding=UTF-8 -classpath "/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre/lib/jfxswt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/lib/ant-javafx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/lib/javafx-mx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/lib/packager.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/lib/tools.jar:/Users/littlehui/WorkSpaces/Home/pattern/out/production/responsbilitychain:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar" com.littlehui.design.responsebilitychain.Demo
Connected to the target VM, address: '127.0.0.1:65034', transport: 'socket'
Error Console::Logger: This is an information.
Error Console::Logger: This is a warn level information.
Error Console::Logger: This is a warn level information.
Error Console::Logger: This is an error information.
Error Console::Logger: This is an error information.
Error Console::Logger: This is an error information.
Disconnected from the target VM, address: '127.0.0.1:65034', transport: 'socket'

Process finished with exit code 0

场景

  • Spring MVC的filter,Interceptor各种Handler等等
  • 日志记录

总结

责任链的特点是单一职责,链式结构。前提是统一的输入端。
在遇到复杂业务,特别是复杂请求时候。输入端是统一的,这时候就可以考虑将业务处理拆分成单一的
职责。再将对象链接起来。这样的好处是,解耦了接收端的处理。并且提升了扩展性能。维护也方便。