责任链模式详解
目录
责任链模式简介
定义
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
核心思想
- 解耦发送者和接收者:请求发送者不需要知道具体哪个对象处理请求
- 动态链式处理:可以在运行时动态构建处理链
- 灵活配置:可以灵活添加、删除、修改处理节点
- 单一职责:每个处理者只负责处理自己能处理的请求
模式结构
- Handler(抽象处理者):定义处理请求的接口,实现后继链
- ConcreteHandler(具体处理者):处理它所负责的请求,可访问它的后继者
- Client(客户端):向链上的具体处理者对象提交请求
核心流程
责任链模式流程图
基本实现流程
1. 定义抽象处理者
// 抽象处理者
public abstract class Handler {
protected Handler nextHandler;
public void setNext(Handler nextHandler) {
this.nextHandler = nextHandler;
}
public Handler getNext() {
return nextHandler;
}
// 处理请求的抽象方法
public abstract void handleRequest(Request request);
// 模板方法:定义处理流程
public final void process(Request request) {
if (canHandle(request)) {
handleRequest(request);
} else if (nextHandler != null) {
nextHandler.process(request);
} else {
System.out.println("无法处理请求: " + request);
}
}
// 判断是否能处理请求
protected abstract boolean canHandle(Request request);
}
2. 定义请求类
// 请求类
public class Request {
private String type;
private String content;
private int level;
public Request(String type, String content, int level) {
this.type = type;
this.content = content;
this.level = level;
}
// getter和setter方法
public String getType() { return type; }
public void setType(String type) { this.type = type; }
public String getContent() { return content; }
public void setContent(String content) { this.content = content; }
public int getLevel() { return level; }
public void setLevel(int level) { this.level = level; }
@Override
public String toString() {
return "Request{" +
"type='" + type + '\'' +
", content='" + content + '\'' +
", level=" + level +
'}';
}
}
3. 实现具体处理者
// 具体处理者 - 初级处理者
public class JuniorHandler extends Handler {
@Override
protected boolean canHandle(Request request) {
return request.getLevel() <= 1;
}
@Override
public void handleRequest(Request request) {
System.out.println("初级处理者处理请求: " + request);
}
}
// 具体处理者 - 中级处理者
public class MiddleHandler extends Handler {
@Override
protected boolean canHandle(Request request) {
return request.getLevel() <= 3;
}
@Override
public void handleRequest(Request request) {
System.out.println("中级处理者处理请求: " + request);
}
}
// 具体处理者 - 高级处理者
public class SeniorHandler extends Handler {
@Override
protected boolean canHandle(Request request) {
return request.getLevel() <= 5;
}
@Override
public void handleRequest(Request request) {
System.out.println("高级处理者处理请求: " + request);
}
}
4. 客户端使用
public class Client {
public static void main(String[] args) {
// 创建处理者
Handler junior = new JuniorHandler();
Handler middle = new MiddleHandler();
Handler senior = new SeniorHandler();
// 构建责任链
junior.setNext(middle);
middle.setNext(senior);
// 创建请求
Request request1 = new Request("简单请求", "处理简单问题", 1);
Request request2 = new Request("复杂请求", "处理复杂问题", 4);
Request request3 = new Request("困难请求", "处理困难问题", 6);
// 处理请求
junior.process(request1);
junior.process(request2);
junior.process(request3);
}
}
重难点分析
重难点1:责任链的构建和管理
问题描述
如何动态构建和管理责任链,支持链的添加、删除、修改。
解决方案
// 责任链管理器
public class ChainManager {
private Handler firstHandler;
private Handler lastHandler;
private List<Handler> handlers = new ArrayList<>();
public ChainManager addHandler(Handler handler) {
if (firstHandler == null) {
firstHandler = handler;
lastHandler = handler;
} else {
lastHandler.setNext(handler);
lastHandler = handler;
}
handlers.add(handler);
return this;
}
public ChainManager removeHandler(Handler handler) {
if (handlers.remove(handler)) {
rebuildChain();
}
return this;
}
public ChainManager insertHandler(Handler handler, int index) {
if (index < 0 || index > handlers.size()) {
throw new IllegalArgumentException("索引超出范围");
}
handlers.add(index, handler);
rebuildChain();
return this;
}
private void rebuildChain() {
firstHandler = null;
lastHandler = null;
for (Handler handler : handlers) {
if (firstHandler == null) {
firstHandler = handler;
lastHandler = handler;
} else {
lastHandler.setNext(handler);
lastHandler = handler;
}
}
}
public void process(Request request) {
if (firstHandler != null) {
firstHandler.process(request);
} else {
System.out.println("责任链为空,无法处理请求");
}
}
public List<Handler> getHandlers() {
return new ArrayList<>(handlers);
}
}
// 使用示例
public class ChainManagerDemo {
public static void main(String[] args) {
ChainManager manager = new ChainManager();
// 添加处理者
manager.addHandler(new JuniorHandler())
.addHandler(new MiddleHandler())
.addHandler(new SeniorHandler());
// 处理请求
Request request = new Request("测试请求", "测试内容", 2);
manager.process(request);
// 动态添加处理者
manager.addHandler(new EmergencyHandler());
// 处理紧急请求
Request emergencyRequest = new Request("紧急请求", "紧急内容", 10);
manager.process(emergencyRequest);
}
}
重难点2:责任链的终止条件
问题描述
如何设置责任链的终止条件,避免无限循环。
解决方案
// 带终止条件的责任链
public abstract class TerminableHandler extends Handler {
protected boolean terminated = false;
public void setTerminated(boolean terminated) {
this.terminated = terminated;
}
public boolean isTerminated() {
return terminated;
}
@Override
public final void process(Request request) {
if (terminated) {
System.out.println("责任链已终止,无法处理请求");
return;
}
if (canHandle(request)) {
handleRequest(request);
// 处理完成后可以选择终止链
if (shouldTerminate(request)) {
terminated = true;
}
} else if (nextHandler != null) {
nextHandler.process(request);
} else {
System.out.println("无法处理请求: " + request);
}
}
// 子类可以重写此方法决定是否终止链
protected boolean shouldTerminate(Request request) {
return false;
}
}
// 具体处理者实现
public class TerminableJuniorHandler extends TerminableHandler {
@Override
protected boolean canHandle(Request request) {
return request.getLevel() <= 1;
}
@Override
public void handleRequest(Request request) {
System.out.println("初级处理者处理请求: " + request);
}
@Override
protected boolean shouldTerminate(Request request) {
// 处理紧急请求后终止链
return "紧急".equals(request.getType());
}
}
重难点3:责任链的性能优化
问题描述
如何优化责任链的性能,避免不必要的处理。
解决方案
// 带缓存的责任链
public class CachedHandler extends Handler {
private final Map<String, Handler> handlerCache = new ConcurrentHashMap<>();
private final Map<String, Boolean> canHandleCache = new ConcurrentHashMap<>();
@Override
public void process(Request request) {
String requestKey = generateRequestKey(request);
// 检查缓存
Boolean canHandle = canHandleCache.get(requestKey);
if (canHandle == null) {
canHandle = canHandle(request);
canHandleCache.put(requestKey, canHandle);
}
if (canHandle) {
handleRequest(request);
} else if (nextHandler != null) {
nextHandler.process(request);
} else {
System.out.println("无法处理请求: " + request);
}
}
private String generateRequestKey(Request request) {
return request.getType() + "_" + request.getLevel();
}
public void clearCache() {
handlerCache.clear();
canHandleCache.clear();
}
}
// 并行处理的责任链
public class ParallelHandler extends Handler {
private final ExecutorService executor = Executors.newFixedThreadPool(10);
@Override
public void process(Request request) {
if (canHandle(request)) {
// 并行处理
CompletableFuture.runAsync(() -> handleRequest(request), executor);
} else if (nextHandler != null) {
nextHandler.process(request);
} else {
System.out.println("无法处理请求: " + request);
}
}
public void shutdown() {
executor.shutdown();
}
}
重难点4:责任链的异常处理
问题描述
如何在责任链中处理异常,确保链的稳定性。
解决方案
// 带异常处理的责任链
public abstract class ExceptionHandler extends Handler {
@Override
public final void process(Request request) {
try {
if (canHandle(request)) {
handleRequest(request);
} else if (nextHandler != null) {
nextHandler.process(request);
} else {
System.out.println("无法处理请求: " + request);
}
} catch (Exception e) {
handleException(request, e);
}
}
protected void handleException(Request request, Exception e) {
System.out.println("处理请求时发生异常: " + e.getMessage());
// 可以选择继续传递给下一个处理者
if (nextHandler != null) {
nextHandler.process(request);
}
}
}
// 具体处理者实现
public class ExceptionHandlingHandler extends ExceptionHandler {
@Override
protected boolean canHandle(Request request) {
return request.getLevel() <= 2;
}
@Override
public void handleRequest(Request request) {
// 模拟可能抛出异常的处理
if (request.getContent().contains("异常")) {
throw new RuntimeException("处理异常");
}
System.out.println("处理请求: " + request);
}
}
Spring中的源码分析
Spring MVC的HandlerInterceptor
// HandlerInterceptor接口
public interface HandlerInterceptor {
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}
// HandlerInterceptorAdapter
public abstract class HandlerInterceptorAdapter implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
// HandlerExecutionChain
public class HandlerExecutionChain {
private final Object handler;
private HandlerInterceptor[] interceptors;
private List<HandlerInterceptor> interceptorList;
private int interceptorIndex = -1;
public HandlerExecutionChain(Object handler) {
this(handler, (HandlerInterceptor[]) null);
}
public HandlerExecutionChain(Object handler, @Nullable HandlerInterceptor... interceptors) {
this.handler = handler;
this.interceptors = interceptors;
}
public void addInterceptor(HandlerInterceptor interceptor) {
initInterceptorList();
this.interceptorList.add(interceptor);
updateInterceptorsArray();
}
public void addInterceptor(int index, HandlerInterceptor interceptor) {
initInterceptorList();
this.interceptorList.add(index, interceptor);
updateInterceptorsArray();
}
public boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
HandlerInterceptor[] interceptors = getInterceptors();
if (!ObjectUtils.isEmpty(interceptors)) {
for (int i = 0; i < interceptors.length; i++) {
HandlerInterceptor interceptor = interceptors[i];
if (!interceptor.preHandle(request, response, this.handler)) {
triggerAfterCompletion(request, response, null);
return false;
}
this.interceptorIndex = i;
}
}
return true;
}
public void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv) throws Exception {
HandlerInterceptor[] interceptors = getInterceptors();
if (!ObjectUtils.isEmpty(interceptors)) {
for (int i = interceptors.length - 1; i >= 0; i--) {
HandlerInterceptor interceptor = interceptors[i];
interceptor.postHandle(request, response, this.handler, mv);
}
}
}
public void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex) throws Exception {
HandlerInterceptor[] interceptors = getInterceptors();
if (!ObjectUtils.isEmpty(interceptors)) {
for (int i = this.interceptorIndex; i >= 0; i--) {
HandlerInterceptor interceptor = interceptors[i];
try {
interceptor.afterCompletion(request, response, this.handler, ex);
} catch (Throwable ex2) {
logger.error("HandlerInterceptor.afterCompletion threw exception", ex2);
}
}
}
}
}
Spring Security的FilterChain
// FilterChainProxy
public class FilterChainProxy extends GenericFilterBean {
private List<SecurityFilterChain> filterChains;
private FilterChainValidator filterChainValidator = new NullFilterChainValidator();
private HttpFirewall firewall = new StrictHttpFirewall();
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
boolean clearContext = request.getAttribute(FILTER_APPLIED) == null;
if (clearContext) {
try {
request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
doFilterInternal(request, response, chain);
} finally {
SecurityContextHolder.clearContext();
request.removeAttribute(FILTER_APPLIED);
}
} else {
doFilterInternal(request, response, chain);
}
}
private void doFilterInternal(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
FirewalledRequest firewallRequest = this.firewall.getFirewalledRequest((HttpServletRequest) request);
HttpServletResponse firewallResponse = this.firewall.getFirewalledResponse((HttpServletResponse) response);
List<Filter> filters = getFilters(firewallRequest);
if (filters == null || filters.size() == 0) {
firewallRequest.reset();
chain.doFilter(firewallRequest, firewallResponse);
return;
}
VirtualFilterChain virtualFilterChain = new VirtualFilterChain(firewallRequest, chain, filters);
virtualFilterChain.doFilter(firewallRequest, firewallResponse);
}
private List<Filter> getFilters(HttpServletRequest request) {
for (SecurityFilterChain chain : filterChains) {
if (chain.matches(request)) {
return chain.getFilters();
}
}
return null;
}
}
// VirtualFilterChain
private static class VirtualFilterChain implements FilterChain {
private final FilterChain originalChain;
private final List<Filter> additionalFilters;
private final FirewalledRequest firewalledRequest;
private final int size;
private int currentPosition = 0;
private VirtualFilterChain(FirewalledRequest firewalledRequest, FilterChain originalChain, List<Filter> additionalFilters) {
this.firewalledRequest = firewalledRequest;
this.originalChain = originalChain;
this.additionalFilters = additionalFilters;
this.size = additionalFilters.size();
}
@Override
public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
if (currentPosition == size) {
if (logger.isDebugEnabled()) {
logger.debug(UrlUtils.buildRequestUrl(firewalledRequest) + " reached end of additional filter chain; proceeding with original chain");
}
originalChain.doFilter(request, response);
} else {
currentPosition++;
Filter nextFilter = additionalFilters.get(currentPosition - 1);
if (logger.isDebugEnabled()) {
logger.debug(UrlUtils.buildRequestUrl(firewalledRequest) + " at position " + currentPosition + " of " + size + " in additional filter chain; firing Filter: '" + nextFilter.getClass().getSimpleName() + "'");
}
nextFilter.doFilter(request, response, this);
}
}
}
具体使用场景
1. 权限验证链
// 权限验证处理器
public abstract class PermissionHandler {
protected PermissionHandler nextHandler;
public void setNext(PermissionHandler nextHandler) {
this.nextHandler = nextHandler;
}
public boolean checkPermission(User user, String resource) {
if (canHandle(user, resource)) {
return handlePermission(user, resource);
} else if (nextHandler != null) {
return nextHandler.checkPermission(user, resource);
} else {
return false;
}
}
protected abstract boolean canHandle(User user, String resource);
protected abstract boolean handlePermission(User user, String resource);
}
// 角色权限验证
public class RolePermissionHandler extends PermissionHandler {
@Override
protected boolean canHandle(User user, String resource) {
return user.getRole() != null;
}
@Override
protected boolean handlePermission(User user, String resource) {
return user.getRole().hasPermission(resource);
}
}
// 资源权限验证
public class ResourcePermissionHandler extends PermissionHandler {
@Override
protected boolean canHandle(User user, String resource) {
return resource.startsWith("/admin/");
}
@Override
protected boolean handlePermission(User user, String resource) {
return user.isAdmin();
}
}
// 时间权限验证
public class TimePermissionHandler extends PermissionHandler {
@Override
protected boolean canHandle(User user, String resource) {
return resource.startsWith("/time/");
}
@Override
protected boolean handlePermission(User user, String resource) {
LocalTime now = LocalTime.now();
return now.isAfter(LocalTime.of(9, 0)) && now.isBefore(LocalTime.of(18, 0));
}
}
// 使用示例
public class PermissionChainDemo {
public static void main(String[] args) {
// 创建权限验证链
PermissionHandler roleHandler = new RolePermissionHandler();
PermissionHandler resourceHandler = new ResourcePermissionHandler();
PermissionHandler timeHandler = new TimePermissionHandler();
roleHandler.setNext(resourceHandler);
resourceHandler.setNext(timeHandler);
// 创建用户
User user = new User("admin", "ADMIN");
// 验证权限
boolean hasPermission1 = roleHandler.checkPermission(user, "/user/profile");
boolean hasPermission2 = roleHandler.checkPermission(user, "/admin/users");
boolean hasPermission3 = roleHandler.checkPermission(user, "/time/report");
System.out.println("用户权限验证结果:");
System.out.println("/user/profile: " + hasPermission1);
System.out.println("/admin/users: " + hasPermission2);
System.out.println("/time/report: " + hasPermission3);
}
}
2. 日志处理链
// 日志处理器
public abstract class LogHandler {
protected LogHandler nextHandler;
public void setNext(LogHandler nextHandler) {
this.nextHandler = nextHandler;
}
public void handleLog(LogEntry logEntry) {
if (canHandle(logEntry)) {
processLog(logEntry);
}
if (nextHandler != null) {
nextHandler.handleLog(logEntry);
}
}
protected abstract boolean canHandle(LogEntry logEntry);
protected abstract void processLog(LogEntry logEntry);
}
// 控制台日志处理器
public class ConsoleLogHandler extends LogHandler {
@Override
protected boolean canHandle(LogEntry logEntry) {
return logEntry.getLevel().ordinal() >= LogLevel.INFO.ordinal();
}
@Override
protected void processLog(LogEntry logEntry) {
System.out.println("控制台日志: " + logEntry);
}
}
// 文件日志处理器
public class FileLogHandler extends LogHandler {
@Override
protected boolean canHandle(LogEntry logEntry) {
return logEntry.getLevel().ordinal() >= LogLevel.WARN.ordinal();
}
@Override
protected void processLog(LogEntry logEntry) {
System.out.println("文件日志: " + logEntry);
}
}
// 邮件日志处理器
public class EmailLogHandler extends LogHandler {
@Override
protected boolean canHandle(LogEntry logEntry) {
return logEntry.getLevel() == LogLevel.ERROR;
}
@Override
protected void processLog(LogEntry logEntry) {
System.out.println("邮件日志: " + logEntry);
}
}
// 使用示例
public class LogChainDemo {
public static void main(String[] args) {
// 创建日志处理链
LogHandler consoleHandler = new ConsoleLogHandler();
LogHandler fileHandler = new FileLogHandler();
LogHandler emailHandler = new EmailLogHandler();
consoleHandler.setNext(fileHandler);
fileHandler.setNext(emailHandler);
// 处理日志
LogEntry infoLog = new LogEntry(LogLevel.INFO, "系统启动");
LogEntry warnLog = new LogEntry(LogLevel.WARN, "内存不足");
LogEntry errorLog = new LogEntry(LogLevel.ERROR, "数据库连接失败");
consoleHandler.handleLog(infoLog);
consoleHandler.handleLog(warnLog);
consoleHandler.handleLog(errorLog);
}
}
3. 订单处理链
// 订单处理器
public abstract class OrderHandler {
protected OrderHandler nextHandler;
public void setNext(OrderHandler nextHandler) {
this.nextHandler = nextHandler;
}
public void processOrder(Order order) {
if (canHandle(order)) {
handleOrder(order);
}
if (nextHandler != null) {
nextHandler.processOrder(order);
}
}
protected abstract boolean canHandle(Order order);
protected abstract void handleOrder(Order order);
}
// 库存验证处理器
public class InventoryHandler extends OrderHandler {
@Override
protected boolean canHandle(Order order) {
return true; // 所有订单都需要验证库存
}
@Override
protected void handleOrder(Order order) {
if (order.getItems().stream().allMatch(item -> item.getStock() >= item.getQuantity())) {
System.out.println("库存验证通过: " + order.getId());
} else {
System.out.println("库存不足: " + order.getId());
order.setStatus(OrderStatus.CANCELLED);
}
}
}
// 支付处理处理器
public class PaymentHandler extends OrderHandler {
@Override
protected boolean canHandle(Order order) {
return order.getStatus() != OrderStatus.CANCELLED;
}
@Override
protected void handleOrder(Order order) {
if (order.getPaymentMethod().isValid()) {
System.out.println("支付处理成功: " + order.getId());
order.setStatus(OrderStatus.PAID);
} else {
System.out.println("支付处理失败: " + order.getId());
order.setStatus(OrderStatus.PAYMENT_FAILED);
}
}
}
// 发货处理处理器
public class ShippingHandler extends OrderHandler {
@Override
protected boolean canHandle(Order order) {
return order.getStatus() == OrderStatus.PAID;
}
@Override
protected void handleOrder(Order order) {
System.out.println("开始发货: " + order.getId());
order.setStatus(OrderStatus.SHIPPED);
}
}
// 使用示例
public class OrderChainDemo {
public static void main(String[] args) {
// 创建订单处理链
OrderHandler inventoryHandler = new InventoryHandler();
OrderHandler paymentHandler = new PaymentHandler();
OrderHandler shippingHandler = new ShippingHandler();
inventoryHandler.setNext(paymentHandler);
paymentHandler.setNext(shippingHandler);
// 创建订单
Order order = new Order("ORDER001", Arrays.asList(
new OrderItem("ITEM001", 2, 10),
new OrderItem("ITEM002", 1, 20)
), new PaymentMethod("CARD", "1234567890"));
// 处理订单
inventoryHandler.processOrder(order);
System.out.println("订单状态: " + order.getStatus());
}
}
面试高频点
面试知识点思维导图
1. 责任链模式的基本概念
问题:什么是责任链模式?
答案要点:
- 多个对象都有机会处理请求,避免请求发送者和接收者之间的耦合
- 将这些对象连成一条链,沿着链传递请求
- 属于行为型设计模式
- 直到有一个对象处理请求为止
问题:责任链模式有哪些角色?
答案要点:
- Handler(抽象处理者):定义处理请求的接口,实现后继链
- ConcreteHandler(具体处理者):处理它所负责的请求,可访问它的后继者
- Client(客户端):向链上的具体处理者对象提交请求
2. 实现方式相关
问题:如何实现责任链模式?
答案要点:
// 1. 定义抽象处理者
public abstract class Handler {
protected Handler nextHandler;
public void setNext(Handler nextHandler) {
this.nextHandler = nextHandler;
}
public abstract void handleRequest(Request request);
}
// 2. 实现具体处理者
public class ConcreteHandler extends Handler {
@Override
public void handleRequest(Request request) {
if (canHandle(request)) {
// 处理请求
} else if (nextHandler != null) {
nextHandler.handleRequest(request);
}
}
protected abstract boolean canHandle(Request request);
}
3. 重难点问题
问题:如何设置责任链的终止条件?
答案要点:
- 检查下一个处理者:如果nextHandler为null,则链结束
- 处理结果控制:根据处理结果决定是否继续传递
- 异常处理:异常情况下可以终止链
- 业务逻辑控制:根据业务需求设置终止条件
问题:责任链模式的性能如何优化?
答案要点:
// 1. 缓存处理结果
public class CachedHandler extends Handler {
private final Map<String, Boolean> cache = new ConcurrentHashMap<>();
@Override
public void handleRequest(Request request) {
String key = generateKey(request);
Boolean canHandle = cache.computeIfAbsent(key, k -> canHandle(request));
if (canHandle) {
// 处理请求
} else if (nextHandler != null) {
nextHandler.handleRequest(request);
}
}
}
// 2. 并行处理
public class ParallelHandler extends Handler {
private final ExecutorService executor = Executors.newFixedThreadPool(10);
@Override
public void handleRequest(Request request) {
if (canHandle(request)) {
executor.submit(() -> processRequest(request));
} else if (nextHandler != null) {
nextHandler.handleRequest(request);
}
}
}
4. Spring中的应用
问题:Spring中如何使用责任链模式?
答案要点:
// 1. HandlerInterceptor链
public class CustomInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
// 预处理逻辑
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
// 后处理逻辑
}
}
// 2. Filter链
public class CustomFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// 处理逻辑
chain.doFilter(request, response);
}
}
5. 设计原则相关
问题:责任链模式体现了哪些设计原则?
答案要点:
- 单一职责:每个处理者只负责处理自己能处理的请求
- 开闭原则:可以添加新的处理者而不修改现有代码
- 依赖倒置:依赖抽象而不是具体实现
- 接口隔离:客户端只依赖需要的接口
6. 实际应用场景
问题:责任链模式适用于哪些场景?
答案要点:
- 权限验证:多级权限验证
- 日志处理:多级日志处理
- 订单处理:订单处理流程
- 异常处理:多级异常处理
- 请求处理:Web请求处理链
- 数据验证:多级数据验证
使用总结
责任链模式的优势
- 解耦:请求发送者和接收者解耦
- 灵活配置:可以动态添加、删除、修改处理者
- 单一职责:每个处理者只负责自己的职责
- 可扩展性:易于添加新的处理者
责任链模式的缺点
- 性能问题:链式调用可能影响性能
- 调试困难:链式调用使调试变得困难
- 循环依赖:可能出现循环依赖问题
- 内存开销:链式调用占用额外内存
使用建议
- 简单场景:只用于简单的处理场景
- 性能考虑:注意链式调用的性能影响
- 异常处理:做好异常处理,避免链中断
- 测试覆盖:确保每个处理者都有测试覆盖
最佳实践
- 明确职责:每个处理者职责明确
- 异常处理:做好异常处理机制
- 性能优化:考虑缓存和并行处理
- 文档注释:为每个处理者添加详细注释
- 单元测试:为每个处理者编写单元测试
与其他模式的对比
- 与装饰器模式:责任链模式是链式处理,装饰器模式是包装处理
- 与策略模式:责任链模式是链式选择,策略模式是单一选择
- 与命令模式:责任链模式是处理请求,命令模式是封装请求
责任链模式是一种有用的行为型设计模式,特别适用于需要多级处理、权限验证、日志处理等场景。通过合理使用责任链模式,可以大大提高系统的灵活性和可维护性。
696

被折叠的 条评论
为什么被折叠?



