责任链模式的作用在于将多个行为串成一条线,让他们有顺序的执行下去,通常是线性结构,也可以是环形结构、树状结构,但是需要其它的设计支持。
责任链模式主要元素:处理者接口、抽象处理类、具体实现类。
优点:扩展性、解耦、动态调整顺序。
例子1:审批功能。拿学校的教务系统来说,如果你请3天以内的假,辅导员审批可以,如果是大于3天小于7天,则需要系领导审批,如果是大于7天小于30天则需要院领导审批,大于30天需要校领导审批。
例子2:日志系统。debug和info级别的日志输出到控制台,warn级别输出到控制台的同时还要写入日志文件,error级别的日志不仅要做前面两个操作,还需要发送错误信息到日志服务器。
例子3:复杂的级联删除操作。存在a、b、c、d......表,表之间都是1:n或1:1关系,当删除a时候,需要把与a相关的b、c、d......都删除,当删除b时候需要把与b相关的c、d......都删除。如果是简单的级联删除并不适合使用责任链模式,这会导致代码变得更加复杂。
以下是例子3的实现代码。(以下例子失去了责任链模式的动态调整顺序这个优点,甚至于我直接将构建责任链的代码提取了出来,固定写了从a节点开始到末尾、从b节点开始到末尾...多个责任链,这并不是最优的处理方法,只是我工作中遇到的问题的解决方法)
1、处理者接口
定义处理请求的方法和设置下一个处理器的方法。
interface DeleteHandler{
/** 控制责任链的前后顺序 **/
void setNext(DeleteHandler next);
/** 主要方法 **/
void myDelete(String... ids);
}
2、抽象处理者类
实现处理者接口,提供了对下一个处理器的引用,并实现了请求的传递逻辑。
abstract class AbstractHandler implements DeleteHandler {
private DeleteHandler next;
@Override
public void setNext(DeleteHandler next) {
this.next = next;
}
@Override
public void myDelete(String... ids) {
if (next != null) {
next.myDelete(ids);
}
}
}
3、具体实现类
实现了具体的处理逻辑。
class DeleteHandlerA extends AbstractHandler {
@Autowired
private AService aService;
@Autowired
private BService bService;
@Override
public void myDelete(String... ids) {
//1、调用a表数据的删除方法
aService.deleteByIds(ids);
//2、查询与a表数据关联的b表数据id
List<String> bIds = bService.getIdsByA(ids);
//3、其它业务代码
......
super.myDelete(bIds);
}
}
class DeleteHandlerB extends AbstractHandler {
@Autowired
private BService bService;
@Autowired
private CService cService;
@Override
public void myDelete(String... ids) {
//1、调用b表数据的删除方法
bService.deleteByIds(ids);
//2、查询与b表数据关联的c表数据id
List<String> cIds = cService.getIdsByB(ids);
//3、其它业务代码
......
super.myDelete(cIds);
}
}
......
4、使用示例
// 构建责任链
DeleteHandler deleteHandlerA = new DeleteHandlerA();
DeleteHandler deleteHandlerB = new DeleteHandlerB();
DeleteHandler deleteHandlerC = new DeleteHandlerC();
......
deleteHandlerA.setNext(deleteHandlerB);
deleteHandlerB.setNext(deleteHandlerC);
......
以下是由ai生成例子2的代码,可以作为对比
// 定义日志处理器接口
interface Logger {
void setNext(Logger next);
void logMessage(String level, String message);
}
// 抽象日志处理器类
abstract class AbstractLogger implements Logger {
protected Logger nextLogger;
@Override
public void setNext(Logger next) {
this.nextLogger = next;
}
protected abstract boolean canHandle(String level);
@Override
public void logMessage(String level, String message) {
if (canHandle(level)) {
writeMessage(level, message);
} else if (nextLogger != null) {
nextLogger.logMessage(level, message);
}
}
protected abstract void writeMessage(String level, String message);
}
// 控制台日志处理器
class ConsoleLogger extends AbstractLogger {
@Override
protected boolean canHandle(String level) {
return "DEBUG".equals(level) || "INFO".equals(level);
}
@Override
protected void writeMessage(String level, String message) {
System.out.println("控制台日志:" + level + " - " + message);
}
}
// 文件日志处理器
class FileLogger extends AbstractLogger {
@Override
protected boolean canHandle(String level) {
return "WARN".equals(level);
}
@Override
protected void writeMessage(String level, String message) {
System.out.println("文件日志:" + level + " - " + message);
// 实际开发中可以写入文件
}
}
// 错误日志处理器
class ErrorLogger extends AbstractLogger {
@Override
protected boolean canHandle(String level) {
return "ERROR".equals(level);
}
@Override
protected void writeMessage(String level, String message) {
System.out.println("错误日志:" + level + " - " + message);
// 实际开发中可以发送到错误日志服务器
}
}
// 客户端代码
public class LoggingClient {
public static void main(String[] args) {
// 构建责任链
Logger consoleLogger = new ConsoleLogger();
Logger fileLogger = new FileLogger();
Logger errorLogger = new ErrorLogger();
consoleLogger.setNext(fileLogger);
fileLogger.setNext(errorLogger);
// 测试不同级别的日志
consoleLogger.logMessage("INFO", "这是一条INFO级别的日志");
consoleLogger.logMessage("WARN", "这是一条WARN级别的日志");
consoleLogger.logMessage("ERROR", "这是一条ERROR级别的日志");
consoleLogger.logMessage("DEBUG", "这是一条DEBUG级别的日志");
}
}