什么是责任链模式?
责任链模式在代码重构中用的比较多,责任链模式就是一个请求,通过一个组装好的责任链来进行处理,责任链根据请求中的参数的不同选择不同的节点来处理问题。 达到请求和处理的解耦。
责任链的使用场景?
责任链本身就是一个更灵活的if….else, 如果代码中有了多个条件判断的时候(多于三个),就可以考虑使用责任链来进行代码的重构,当然责任链也有很多其他的应用场景,如struts的过滤器就是一种典型的责任链模式。 同样我们在实现自己的过滤器需求的时候也可以使用责任链模式。
如何实现责任链模式?
用网上最常见的一个例子说明责任链模式,先看个需求: 打印日志的时候log4J会有一个日志的级别:
debug级别: 会显示debug\info\error三种日志信息,
info级别: 显示info/error
error级别: 只显示error级别的信息
那如何实现这个需求呢?
第一种if.. else方式: 伪代码如下
if(debug){
print(debug);
print(info);
print(error);
}else if(info){
print(info);
print(error);
}else if(error){
print(error);
}
代码什么感觉? 第一感觉很low, 如果出现多个if…else if 的时候我们就可以考虑一下是不是可以用责任链来进行重构呢? 我们来看一下重构之后的代码: 读者最好复制运行一下就懂了。
public abstract class AbstractLogger {
public static int DEBUG = 1;
public static int INFO = 2;
public static int ERROR = 3;
public int level;
//责任链中的下一个元素
public 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);
}
}
protected abstract void write(String message);
}
public class DebugLogger extends AbstractLogger {
public DebugLogger(int level){
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("debug Logger: " + message);
}
}
public class ErrorLogger extends AbstractLogger {
public ErrorLogger(int level){
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("Error Logger: " + message);
}
}
public class InfoLogger extends AbstractLogger {
public InfoLogger(int level){
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("info Logger: " + message);
}
}
组装和测试:
public class ChainPatternDemo {
private static AbstractLogger getChainOfLoggers(){
AbstractLogger debugLogger = new DebugLogger(AbstractLogger.DEBUG);
AbstractLogger infoLogger = new InfoLogger(AbstractLogger.INFO);
AbstractLogger errorLogger = new ErrorLogger(AbstractLogger.ERROR);
debugLogger.setNextLogger(infoLogger);
infoLogger.setNextLogger(errorLogger);
return debugLogger;
}
public static void main(String[] args) {
AbstractLogger loggerChain = getChainOfLoggers();
loggerChain.logMessage(AbstractLogger.DEBUG,
"This is an debug level information.");
loggerChain.logMessage(AbstractLogger.INFO,
"This is an info information.");
loggerChain.logMessage(AbstractLogger.ERROR,
"This is an error information.");
}
}
运行结果:
debug Logger: This is an debug level information.
info Logger: This is an debug level information.
Error Logger: This is an debug level information.
info Logger: This is an info information.
Error Logger: This is an info information.
Error Logger: This is an error information.
可以看出debug级别输出三条信息,info两条, error只有一条,实现了我们的需求。
对比来看责任链有什么优点呢? 代码简洁易懂,逻辑清晰?不不不,第一高大上了对不对? 第二,最重要的是方便来扩展,如果有新的需求了, 在加一个级别怎么办呢? 第一种方式是加一个if else 在来一个呢? 再加一个。。。。 第二种方式就比较好了,新添加一个类就行了,维护这个类到责任链中。
责任链有缺点么?
1、不能保证请求一定被接收。 【如果级别设置为4就不会有处理,用注解配合枚举可以解决】
2、系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。