1、概述
责任链模式用于弱化请求发生者和请求处理者之间的关系。当多个对象都可以对请求进行处理,但不同的对象能处理的请求类型不同时,可以通过指向另一个对象的引用把这些对象连成一条责任链。当 Client 发出一个请求时,并不知道具体由哪个对象进行处理,它看到的只是一条责任链,将请求直接交给责任链,请求会在责任链中传递,直到找到一个能够进行处理的对象或者遍历结束找不到一个能够处理的对象为止。
Java 语言中的异常处理机制就是责任链模式的一个典型应用例子。可能抛出异常的语句由 try-catch 包围,在 try-catch 中指定能处理的异常类型。当一个 Java 异常产生时,由包围产生异常的语句的最里层的 try-catch 进行处理,如果该层 try-catch 不能处理,则继续将异常抛向上一层的 try-catch 处理,最终直到 main 函数中如果还没有相应的 try-catch 处理,则 Java 程序打印出异常信息,Java 虚拟机也同时结束运行。
2、代码
package com.study.designPattern.chain.pattern;
/**
* 创建抽象的记录器类。
* Created by guobing on 2016/4/25.
*/
public abstract class AbstractLogger {
public static int INFO = 1;
public static int DEBUG = 2;
public static int ERROR = 3;
// 包级访问权限
protected int level;
//责任链中的下一个元素
protected 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);
}
package com.study.designPattern.chain.pattern;
/**
* Created by guobing on 2016/4/25.
*/
public class ConsoleLogger extends AbstractLogger {
public ConsoleLogger(int level) {
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("Standard Console::Logger: " + message);
}
}
package com.study.designPattern.chain.pattern;
/**
* Created by guobing on 2016/4/25.
*/
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);
}
}
package com.study.designPattern.chain.pattern;
/**
* Created by guobing on 2016/4/25.
*/
public class FileLogger extends AbstractLogger {
public FileLogger(int level) {
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("Standard File::Logger: " + message);
}
}
package com.study.designPattern.chain.pattern;
/**
* 责任链模式
* 创建不同类型的记录器。赋予它们不同的错误级别,并在每个记录器中设置下一个记录器。每个记录器中的下一个记录器代表的是链的一部分。
* Created by guobing on 2016/4/25.
*/
public class ChainPattern {
private static AbstractLogger getChainOfLoggers(){
AbstractLogger errorLogger = new ErrorLogger(AbstractLogger.ERROR);
AbstractLogger fileLogger = new FileLogger(AbstractLogger.DEBUG);
AbstractLogger consoleLogger = new ConsoleLogger(AbstractLogger.INFO);
errorLogger.setNextLogger(fileLogger);
fileLogger.setNextLogger(consoleLogger);
return errorLogger;
}
public static void main(String[] args) {
AbstractLogger loggerChain = getChainOfLoggers();
loggerChain.logMessage(AbstractLogger.INFO, "This is an information.");
loggerChain.logMessage(AbstractLogger.DEBUG, "This is an debug level information.");
loggerChain.logMessage(AbstractLogger.ERROR, "This is an error information.");
}
}
3、总结
责任链模式在请求 - 处理程序中,弱化了二者之间的关联,降低了请求发生者和请求处理者之间的耦合程度,请求发生者无需知道一个请求具体由哪个对象进行处理,只是把请求交给责任链。同时这也使得程序中责任划分更加的细化,每个请求处理者对象只有一种职责,只能处理对应类型的请求,这符合面向对象的设计原则,不同的请求处理对象之间只是通过一个引用进行关联。
同时责任链模式也会带来一些缺点,首先,请求不能保证都能被处理,如果在责任链中找不到一个合适的请求处理对象,则请求不能被处理。其次,请求处理的速度可能相对较慢,由于请求发生者并不知道请求具体应该交给哪个请求处理对象处理,请求需要在责任链中遍历,直到找到一个合适的请求处理对象。