顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。
在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。
介绍
意图:避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。
主要解决:职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了。
优点: 1、降低耦合度。它将请求的发送者和接收者解耦。 2、简化了对象。使得对象不需要知道链的结构。 3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。 4、增加新的请求处理类很方便。
缺点:并不保证请求一定会被执行,如果没有任何处理器处理的话,请求可能会落到责任链的尾端
何时使用:在处理消息的时候以过滤很多道。
如何解决:拦截的类都实现统一接口。
实现
我们创建抽象类 AbstractLogger,带有详细的日志记录级别。然后我们创建三种类型的记录器,都扩展了 AbstractLogger。每个记录器消息的级别是否等于自己的级别,如果是则相应地打印出来,否则将不打印并把消息传给下一个记录器。
第一步、创建责任链统一接口
package chain.demo.logger;
/**
* 创建责任链统一接口,带有详细的日志记录级别
*/
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;
}
/**
* 查看当前级别是否大于当前对象
* @param level
* @param message
*/
public void logMessage(int level, String message){
if(this.level == level){
log(message);
}
else
{
if(nextLogger !=null){
nextLogger.logMessage(level, message);
}
}
}
/**
* 输出日志
* @param message
*/
abstract protected void log(String message);
}
第二部,创建责任链,责任链中的处理器都有下一个处理器的引用,当自身处理不了当前信息时,抛给下一个处理器
package chain.demo.logger;
/**
* 创建具体责任链,责任链中的处理器都有下一个处理器的引用,当自身处理不了当前信息时,抛给下一个处理器
*/
public class ConsoleLogger extends AbstractLogger {
/**
* 指定nextLogger为DebugLogger
*/
public ConsoleLogger(){
this.level = AbstractLogger.INFO;
setNextLogger(new DebugLogger());
}
@Override
protected void log(String message) {
System.out.println("Console Logger: " + message);
}
}
package chain.demo.logger;
public class DebugLogger extends AbstractLogger {
/**
* 指定nextLogger为ErrorLogger
*/
public DebugLogger(){
this.level = AbstractLogger.DEBUG;
setNextLogger(new ErrorLogger());
}
@Override
protected void log(String message) {
System.out.println("Debug Logger: " + message);
}
}
package chain.demo.logger;
/**
* 责任链的底端,后面没有责任链了
*/
public class ErrorLogger extends AbstractLogger {
/**
* nextLogger设置为null
* 扩展时将此更改为新的Logger
*/
public ErrorLogger(){
this.level = AbstractLogger.ERROR;
setNextLogger(null);;
}
@Override
public void log(String message) {
System.out.println("Error logger: " + message);
}
}
第三步、客户端发消息,测试
package chain.demo;
import chain.demo.logger.AbstractLogger;
import chain.demo.logger.ConsoleLogger;
public class Client {
public static void main(String[] args) {
/**
* 暴露最低等级既可
*/
AbstractLogger consoleLogger = new ConsoleLogger();
consoleLogger.logMessage(3, "错误信息");
System.out.println();
consoleLogger.logMessage(2, "测试信息");
System.out.println();
consoleLogger.logMessage(1, "控制台信息");
}
}
Error logger: 错误信息
Debug Logger: 测试信息
Console Logger: 控制台信息