当前位置: 首页 > news >正文

设计模式-装饰器模式详解

装饰器模式详解

1. 装饰器模式简介

1.1 定义

装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许向一个现有的对象添加新的功能,同时又不改变其结构。装饰器模式通过创建一个包装对象来动态地给一个对象添加一些额外的职责。

1.2 核心思想

  • 动态扩展:在运行时动态地给对象添加功能
  • 透明包装:装饰器与被装饰的对象具有相同的接口
  • 组合优于继承:通过组合的方式实现功能扩展,避免继承的复杂性

1.3 模式结构

contains
«interface»
Component
+operation()
ConcreteComponent
+operation()
Decorator
-component: Component
+Decorator(Component)
+operation()
ConcreteDecoratorA
+operation()
+addedBehavior()
ConcreteDecoratorB
+operation()
+addedBehavior()

结构说明:

  • Component(抽象组件):定义对象的接口,可以给这些对象动态地添加职责
  • ConcreteComponent(具体组件):定义具体的对象,也可以给这个对象添加一些职责
  • Decorator(抽象装饰器):维护一个指向Component对象的引用,并定义一个与Component接口一致的接口
  • ConcreteDecorator(具体装饰器):向组件添加职责

1.4 工作流程

客户端装饰器被装饰对象调用operation()执行装饰逻辑调用被装饰对象的operation()返回结果执行后续装饰逻辑返回最终结果客户端装饰器被装饰对象

2. 应用场景

2.1 典型应用场景

  1. 功能增强:在不修改原有类的基础上,动态地添加功能
  2. 职责分离:将不同的职责分离到不同的装饰器中
  3. 替代继承:当使用继承会导致类爆炸时,使用装饰器模式
  4. 运行时扩展:需要在运行时决定如何组合功能

2.2 实际应用示例

2.2.1 Java I/O流装饰器示例
// 基础组件接口
public interface DataSource {void writeData(String data);String readData();
}// 具体组件
public class FileDataSource implements DataSource {private String filename;public FileDataSource(String filename) {this.filename = filename;}@Overridepublic void writeData(String data) {System.out.println("写入文件 " + filename + ": " + data);}@Overridepublic String readData() {return "从文件 " + filename + " 读取数据";}
}// 抽象装饰器
public abstract class DataSourceDecorator implements DataSource {protected DataSource wrappee;public DataSourceDecorator(DataSource source) {this.wrappee = source;}@Overridepublic void writeData(String data) {wrappee.writeData(data);}@Overridepublic String readData() {return wrappee.readData();}
}// 加密装饰器
public class EncryptionDecorator extends DataSourceDecorator {public EncryptionDecorator(DataSource source) {super(source);}@Overridepublic void writeData(String data) {String encryptedData = encrypt(data);super.writeData(encryptedData);}@Overridepublic String readData() {String encryptedData = super.readData();return decrypt(encryptedData);}private String encrypt(String data) {return "加密(" + data + ")";}private String decrypt(String data) {return data.replace("加密(", "").replace(")", "");}
}// 压缩装饰器
public class CompressionDecorator extends DataSourceDecorator {public CompressionDecorator(DataSource source) {super(source);}@Overridepublic void writeData(String data) {String compressedData = compress(data);super.writeData(compressedData);}@Overridepublic String readData() {String compressedData = super.readData();return decompress(compressedData);}private String compress(String data) {return "压缩(" + data + ")";}private String decompress(String data) {return data.replace("压缩(", "").replace(")", "");}
}// 使用示例
public class DecoratorDemo {public static void main(String[] args) {// 基础文件数据源DataSource source = new FileDataSource("data.txt");// 添加加密功能DataSource encryptedSource = new EncryptionDecorator(source);// 添加压缩功能DataSource compressedSource = new CompressionDecorator(encryptedSource);// 使用装饰后的数据源compressedSource.writeData("Hello World");String data = compressedSource.readData();System.out.println("读取数据: " + data);}
}
2.2.2 缓存装饰器示例
// 服务接口
public interface UserService {User getUserById(Long id);void saveUser(User user);
}// 具体服务实现
@Service
public class UserServiceImpl implements UserService {@Overridepublic User getUserById(Long id) {System.out.println("从数据库查询用户: " + id);// 模拟数据库查询return new User(id, "用户" + id);}@Overridepublic void saveUser(User user) {System.out.println("保存用户到数据库: " + user);}
}// 缓存装饰器
@Component
public class CachedUserService implements UserService {private final UserService userService;private final Map<Long, User> cache = new ConcurrentHashMap<>();public CachedUserService(UserService userService) {this.userService = userService;}@Overridepublic User getUserById(Long id) {// 先从缓存获取User cachedUser = cache.get(id);if (cachedUser != null) {System.out.println("从缓存获取用户: " + id);return cachedUser;}// 缓存未命中,从数据库查询User user = userService.getUserById(id);cache.put(id, user);return user;}@Overridepublic void saveUser(User user) {userService.saveUser(user);// 更新缓存cache.put(user.getId(), user);}
}// 日志装饰器
@Component
public class LoggedUserService implements UserService {private final UserService userService;private static final Logger logger = LoggerFactory.getLogger(LoggedUserService.class);public LoggedUserService(UserService userService) {this.userService = userService;}@Overridepublic User getUserById(Long id) {logger.info("开始查询用户: {}", id);long startTime = System.currentTimeMillis();try {User user = userService.getUserById(id);long endTime = System.currentTimeMillis();logger.info("查询用户完成: {}, 耗时: {}ms", user, endTime - startTime);return user;} catch (Exception e) {logger.error("查询用户失败: {}", id, e);throw e;}}@Overridepublic void saveUser(User user) {logger.info("开始保存用户: {}", user);userService.saveUser(user);logger.info("保存用户完成: {}", user);}
}// 组合使用
@Configuration
public class ServiceConfig {@Beanpublic UserService userService() {UserService baseService = new UserServiceImpl();UserService cachedService = new CachedUserService(baseService);return new LoggedUserService(cachedService);}
}
2.2.3 Web中间件装饰器示例
// 请求处理器接口
public interface RequestHandler {void handle(HttpServletRequest request, HttpServletResponse response);
}// 基础处理器
@Component
public class BasicRequestHandler implements RequestHandler {@Overridepublic void handle(HttpServletRequest request, HttpServletResponse response) {System.out.println("处理业务逻辑");}
}// 认证装饰器
@Component
public class AuthenticationDecorator implements RequestHandler {private final RequestHandler handler;public AuthenticationDecorator(RequestHandler handler) {this.handler = handler;}@Overridepublic void handle(HttpServletRequest request, HttpServletResponse response) {if (isAuthenticated(request)) {handler.handle(request, response);} else {response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);}}private boolean isAuthenticated(HttpServletRequest request) {String token = request.getHeader("Authorization");return token != null && token.startsWith("Bearer ");}
}// 日志装饰器
@Component
public class LoggingDecorator implements RequestHandler {private final RequestHandler handler;private static final Logger logger = LoggerFactory.getLogger(LoggingDecorator.class);public LoggingDecorator(RequestHandler handler) {this.handler = handler;}@Overridepublic void handle(HttpServletRequest request, HttpServletResponse response) {logger.info("请求开始: {} {}", request.getMethod(), request.getRequestURI());long startTime = System.currentTimeMillis();try {handler.handle(request, response);long endTime = System.currentTimeMillis();logger.info("请求完成: 状态码={}, 耗时={}ms", response.getStatus(), endTime - startTime);} catch (Exception e) {logger.error("请求处理失败", e);throw e;}}
}// 限流装饰器
@Component
public class RateLimitDecorator implements RequestHandler {private final RequestHandler handler;private final Map<String, AtomicInteger> requestCounts = new ConcurrentHashMap<>();private final int maxRequestsPerMinute = 100;public RateLimitDecorator(RequestHandler handler) {this.handler = handler;}@Overridepublic void handle(HttpServletRequest request, HttpServletResponse response) {String clientIp = getClientIp(request);AtomicInteger count = requestCounts.computeIfAbsent(clientIp, k -> new AtomicInteger(0));if (count.incrementAndGet() > maxRequestsPerMinute) {response.setStatus(HttpServletResponse.SC_TOO_MANY_REQUESTS);return;}handler.handle(request, response);}private String getClientIp(HttpServletRequest request) {String xForwardedFor = request.getHeader("X-Forwarded-For");if (xForwardedFor != null && !xForwardedFor.isEmpty()) {return xForwardedFor.split(",")[0];}return request.getRemoteAddr();}
}// 配置组合
@Configuration
public class HandlerConfig {@Beanpublic RequestHandler requestHandler() {RequestHandler baseHandler = new BasicRequestHandler();RequestHandler loggedHandler = new LoggingDecorator(baseHandler);RequestHandler rateLimitedHandler = new RateLimitDecorator(loggedHandler);return new AuthenticationDecorator(rateLimitedHandler);}
}

3. 重难点分析

3.1 重点

3.1.1 接口一致性

理论:装饰器必须与被装饰对象实现相同的接口

案例:接口不一致导致的问题

// ❌ 错误示例:接口不一致
public interface DataProcessor {String process(String data);
}public class BasicProcessor implements DataProcessor {@Overridepublic String process(String data) {return "处理: " + data;}
}// 错误的装饰器 - 接口不匹配
public class WrongDecorator {private DataProcessor processor;public WrongDecorator(DataProcessor processor) {this.processor = processor;}// 缺少process方法,无法作为DataProcessor使用public String enhancedProcess(String data) {return "增强处理: " + processor.process(data);}
}// ✅ 正确示例:接口一致
public class CorrectDecorator implements DataProcessor {private DataProcessor processor;public CorrectDecorator(DataProcessor processor) {this.processor = processor;}@Overridepublic String process(String data) {return "增强处理: " + processor.process(data);}
}
3.1.2 组合关系

理论:装饰器持有被装饰对象的引用

案例:组合关系的正确实现

// 基础服务接口
public interface PaymentService {void pay(BigDecimal amount);void refund(BigDecimal amount);
}// 基础实现
public class BasicPaymentService implements PaymentService {@Overridepublic void pay(BigDecimal amount) {System.out.println("支付: " + amount);}@Overridepublic void refund(BigDecimal amount) {System.out.println("退款: " + amount);}
}// 正确的装饰器实现
public class LoggingPaymentDecorator implements PaymentService {private final PaymentService paymentService; // 组合关系private final Logger logger = LoggerFactory.getLogger(LoggingPaymentDecorator.class);public LoggingPaymentDecorator(PaymentService paymentService) {this.paymentService = paymentService; // 持有被装饰对象的引用}@Overridepublic void pay(BigDecimal amount) {logger.info("支付开始: {}", amount);paymentService.pay(amount); // 委托给被装饰对象logger.info("支付完成: {}", amount);}@Overridepublic void refund(BigDecimal amount) {logger.info("退款开始: {}", amount);paymentService.refund(amount);logger.info("退款完成: {}", amount);}
}
3.1.3 透明性

理论:客户端代码无需知道是否使用了装饰器

案例:透明性演示

public class PaymentClient {public static void main(String[] args) {// 客户端代码完全一样,无论是否使用装饰器PaymentService service = createPaymentService();// 客户端无需知道service是否被装饰service.pay(new BigDecimal("100.00"));service.refund(new BigDecimal("50.00"));}private static PaymentService createPaymentService() {PaymentService baseService = new BasicPaymentService();// 可以随时添加或移除装饰器,客户端代码不变return new LoggingPaymentDecorator(baseService);// 或者:return new ValidationPaymentDecorator(baseService);// 或者:return baseService; // 不使用装饰器}
}
3.1.4 灵活性

理论:可以任意组合多个装饰器

案例:装饰器组合的灵活性

// 验证装饰器
public class ValidationPaymentDecorator implements PaymentService {private final PaymentService paymentService;public ValidationPaymentDecorator(PaymentService paymentService) {this.paymentService = paymentService;}@Overridepublic void pay(BigDecimal amount) {if (amount.compareTo(BigDecimal.ZERO) <= 0) {throw new IllegalArgumentException("支付金额必须大于0");}paymentService.pay(amount);}@Overridepublic void refund(BigDecimal amount) {if (amount.compareTo(BigDecimal.ZERO) <= 0) {throw new IllegalArgumentException("退款金额必须大于0");}paymentService.refund(amount);}
}// 监控装饰器
public class MonitoringPaymentDecorator implements PaymentService {private final PaymentService paymentService;private final MeterRegistry meterRegistry;public MonitoringPaymentDecorator(PaymentService paymentService, MeterRegistry meterRegistry) {this.paymentService = paymentService;this.meterRegistry = meterRegistry;}@Overridepublic void pay(BigDecimal amount) {Timer.Sample sample = Timer.start(meterRegistry);try {paymentService.pay(amount);meterRegistry.counter("payment.success").increment();} catch (Exception e) {meterRegistry.counter("payment.error").increment();throw e;} finally {sample.stop(Timer.builder("payment.duration").register(meterRegistry));}}@Overridepublic void refund(BigDecimal amount) {// 类似的监控逻辑paymentService.refund(amount);}
}// 灵活的组合方式
public class PaymentServiceFactory {public static PaymentService createService(boolean enableLogging, boolean enableValidation, boolean enableMonitoring) {PaymentService service = new BasicPaymentService();if (enableLogging) {service = new LoggingPaymentDecorator(service);}if (enableValidation) {service = new ValidationPaymentDecorator(service);}if (enableMonitoring) {service = new MonitoringPaymentDecorator(service, meterRegistry);}return service;}
}

3.2 难点

3.2.1 设计复杂性

理论:需要设计合理的抽象层

案例:设计复杂性的挑战

// ❌ 设计过于复杂 - 抽象层过多
public abstract class AbstractPaymentDecorator implements PaymentService {protected PaymentService paymentService;public AbstractPaymentDecorator(PaymentService paymentService) {this.paymentService = paymentService;}
}public abstract class LoggingDecorator extends AbstractPaymentDecorator {protected Logger logger;public LoggingDecorator(PaymentService paymentService) {super(paymentService);this.logger = LoggerFactory.getLogger(getClass());}
}public abstract class ValidationDecorator extends AbstractPaymentDecorator {protected void validateAmount(BigDecimal amount) {if (amount.compareTo(BigDecimal.ZERO) <= 0) {throw new IllegalArgumentException("金额必须大于0");}}
}// 具体实现变得复杂
public class LoggingValidationPaymentDecorator extends ValidationDecorator {private Logger logger = LoggerFactory.getLogger(LoggingValidationPaymentDecorator.class);public LoggingValidationPaymentDecorator(PaymentService paymentService) {super(paymentService);}@Overridepublic void pay(BigDecimal amount) {logger.info("支付开始");validateAmount(amount);paymentService.pay(amount);logger.info("支付完成");}@Overridepublic void refund(BigDecimal amount) {logger.info("退款开始");validateAmount(amount);paymentService.refund(amount);logger.info("退款完成");}
}// ✅ 简化设计 - 职责单一
public class SimpleLoggingDecorator implements PaymentService {private final PaymentService paymentService;private final Logger logger = LoggerFactory.getLogger(SimpleLoggingDecorator.class);public SimpleLoggingDecorator(PaymentService paymentService) {this.paymentService = paymentService;}@Overridepublic void pay(BigDecimal amount) {logger.info("支付: {}", amount);paymentService.pay(amount);}@Overridepublic void refund(BigDecimal amount) {logger.info("退款: {}", amount);paymentService.refund(amount);}
}
3.2.2 调试困难

理论:多层装饰器可能导致调试复杂

案例:调试困难的场景

// 多层装饰器链
public class DebuggingExample {public static void main(String[] args) {PaymentService service = new BasicPaymentService();service = new LoggingDecorator(service);service = new ValidationDecorator(service);service = new MonitoringDecorator(service);service = new RetryDecorator(service);service = new CircuitBreakerDecorator(service);// 当出现异常时,很难定位是哪个装饰器的问题try {service.pay(new BigDecimal("-100")); // 负数金额} catch (Exception e) {// 异常堆栈可能很长,难以定位问题e.printStackTrace();}}
}// 解决方案:添加调试信息
public class DebugLoggingDecorator implements PaymentService {private final PaymentService paymentService;private final Logger logger = LoggerFactory.getLogger(DebugLoggingDecorator.class);private final String decoratorName;public DebugLoggingDecorator(PaymentService paymentService, String decoratorName) {this.paymentService = paymentService;this.decoratorName = decoratorName;}@Overridepublic void pay(BigDecimal amount) {logger.debug("{} - 支付开始: {}", decoratorName, amount);try {paymentService.pay(amount);logger.debug("{} - 支付成功: {}", decoratorName, amount);} catch (Exception e) {logger.error("{} - 支付失败: {}, 错误: {}", decoratorName, amount, e.getMessage());throw e;}}@Overridepublic void refund(BigDecimal amount) {// 类似的调试逻辑paymentService.refund(amount);}
}
3.2.3 性能考虑

理论:多层装饰器可能影响性能

案例:性能问题分析

// 性能测试装饰器
public class PerformanceTestDecorator implements PaymentService {private final PaymentService paymentService;private final String decoratorName;public PerformanceTestDecorator(PaymentService paymentService, String decoratorName) {this.paymentService = paymentService;this.decoratorName = decoratorName;}@Overridepublic void pay(BigDecimal amount) {long startTime = System.nanoTime();try {paymentService.pay(amount);} finally {long endTime = System.nanoTime();long duration = endTime - startTime;System.out.println(decoratorName + " 耗时: " + duration + " 纳秒");}}@Overridepublic void refund(BigDecimal amount) {paymentService.refund(amount);}
}// 性能测试
public class PerformanceTest {public static void main(String[] args) {PaymentService service = new BasicPaymentService();// 测试不同装饰器层数的性能for (int i = 1; i <= 10; i++) {service = new PerformanceTestDecorator(service, "装饰器" + i);}// 执行测试long startTime = System.nanoTime();for (int i = 0; i < 1000; i++) {service.pay(new BigDecimal("100"));}long endTime = System.nanoTime();System.out.println("总耗时: " + (endTime - startTime) + " 纳秒");}
}// 性能优化:减少不必要的装饰器
public class OptimizedPaymentService implements PaymentService {private final PaymentService paymentService;private final boolean enableLogging;private final boolean enableValidation;private final Logger logger = LoggerFactory.getLogger(OptimizedPaymentService.class);public OptimizedPaymentService(PaymentService paymentService, boolean enableLogging, boolean enableValidation) {this.paymentService = paymentService;this.enableLogging = enableLogging;this.enableValidation = enableValidation;}@Overridepublic void pay(BigDecimal amount) {if (enableValidation && amount.compareTo(BigDecimal.ZERO) <= 0) {throw new IllegalArgumentException("金额必须大于0");}if (enableLogging) {logger.info("支付: {}", amount);}paymentService.pay(amount);}@Overridepublic void refund(BigDecimal amount) {if (enableValidation && amount.compareTo(BigDecimal.ZERO) <= 0) {throw new IllegalArgumentException("金额必须大于0");}if (enableLogging) {logger.info("退款: {}", amount);}paymentService.refund(amount);}
}
3.2.4 类型安全

理论:需要确保类型安全

案例:类型安全问题

// ❌ 类型不安全的装饰器
public class UnsafeDecorator {private Object target; // 使用Object类型,不安全public UnsafeDecorator(Object target) {this.target = target;}public Object process(Object data) {// 需要强制类型转换,可能抛出ClassCastExceptionif (target instanceof StringProcessor) {return ((StringProcessor) target).process((String) data);}return data;}
}// ✅ 类型安全的装饰器
public class SafeStringDecorator implements StringProcessor {private final StringProcessor stringProcessor; // 使用具体类型public SafeStringDecorator(StringProcessor stringProcessor) {this.stringProcessor = stringProcessor;}@Overridepublic String process(String data) {// 类型安全,无需强制转换return "装饰: " + stringProcessor.process(data);}
}// 泛型装饰器,提供更好的类型安全
public class GenericDecorator<T> implements Processor<T> {private final Processor<T> processor;public GenericDecorator(Processor<T> processor) {this.processor = processor;}@Overridepublic T process(T data) {return processor.process(data);}
}

3.3 常见陷阱

3.3.1 装饰器链过长导致性能问题

案例:链过长的问题

// ❌ 装饰器链过长
public class LongChainExample {public static void main(String[] args) {PaymentService service = new BasicPaymentService();// 创建过长的装饰器链for (int i = 0; i < 100; i++) {service = new LoggingDecorator(service);}// 性能问题:每次调用都要经过100层装饰器service.pay(new BigDecimal("100"));}
}// ✅ 解决方案:合并装饰器
public class CombinedDecorator implements PaymentService {private final PaymentService paymentService;private final Logger logger = LoggerFactory.getLogger(CombinedDecorator.class);private final boolean enableValidation;private final boolean enableMonitoring;public CombinedDecorator(PaymentService paymentService, boolean enableValidation, boolean enableMonitoring) {this.paymentService = paymentService;this.enableValidation = enableValidation;this.enableMonitoring = enableMonitoring;}@Overridepublic void pay(BigDecimal amount) {if (enableValidation && amount.compareTo(BigDecimal.ZERO) <= 0) {throw new IllegalArgumentException("金额必须大于0");}if (enableMonitoring) {logger.info("支付开始: {}", amount);}paymentService.pay(amount);if (enableMonitoring) {logger.info("支付完成: {}", amount);}}@Overridepublic void refund(BigDecimal amount) {// 类似的合并逻辑paymentService.refund(amount);}
}
3.3.2 忘记调用被装饰对象的方法

案例:忘记委托的问题

// ❌ 忘记调用被装饰对象的方法
public class ForgotDelegateDecorator implements PaymentService {private final PaymentService paymentService;public ForgotDelegateDecorator(PaymentService paymentService) {this.paymentService = paymentService;}@Overridepublic void pay(BigDecimal amount) {System.out.println("支付日志: " + amount);// 忘记调用 paymentService.pay(amount);// 导致实际支付逻辑没有执行}@Overridepublic void refund(BigDecimal amount) {System.out.println("退款日志: " + amount);// 忘记调用 paymentService.refund(amount);}
}// ✅ 正确的实现
public class CorrectDelegateDecorator implements PaymentService {private final PaymentService paymentService;public CorrectDelegateDecorator(PaymentService paymentService) {this.paymentService = paymentService;}@Overridepublic void pay(BigDecimal amount) {System.out.println("支付日志: " + amount);paymentService.pay(amount); // 记得委托给被装饰对象}@Overridepublic void refund(BigDecimal amount) {System.out.println("退款日志: " + amount);paymentService.refund(amount); // 记得委托给被装饰对象}
}
3.3.3 装饰器之间的依赖关系处理不当

案例:依赖关系问题

// ❌ 装饰器依赖关系处理不当
public class DependencyProblemExample {public static void main(String[] args) {PaymentService service = new BasicPaymentService();// 错误的顺序:验证在日志之前,但验证失败时日志不会记录service = new ValidationDecorator(service);service = new LoggingDecorator(service);try {service.pay(new BigDecimal("-100")); // 验证失败,日志不会记录} catch (Exception e) {// 日志装饰器没有机会记录异常}}
}// ✅ 正确的依赖关系处理
public class CorrectDependencyExample {public static void main(String[] args) {PaymentService service = new BasicPaymentService();// 正确的顺序:日志在验证之前,可以记录所有操作service = new LoggingDecorator(service);service = new ValidationDecorator(service);try {service.pay(new BigDecimal("-100")); // 验证失败,但日志会记录} catch (Exception e) {// 日志装饰器已经记录了异常}}
}// 或者使用装饰器工厂来管理依赖关系
public class DecoratorFactory {public static PaymentService createService(boolean enableLogging, boolean enableValidation) {PaymentService service = new BasicPaymentService();// 按照正确的依赖顺序添加装饰器if (enableLogging) {service = new LoggingDecorator(service);}if (enableValidation) {service = new ValidationDecorator(service);}return service;}
}

4. 在Spring中的应用

4.1 Spring AOP中的装饰器模式

Spring AOP本质上就是装饰器模式的实现,通过代理对象来增强目标对象的功能。

// 目标接口
public interface UserService {void saveUser(User user);
}// 目标实现
@Service
public class UserServiceImpl implements UserService {@Overridepublic void saveUser(User user) {// 保存用户逻辑}
}// 装饰器(AOP切面)
@Aspect
@Component
public class LoggingAspect {@Around("execution(* com.example.service.UserService.*(..))")public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("方法执行前");Object result = joinPoint.proceed();System.out.println("方法执行后");return result;}
}

4.2 Spring MVC中的装饰器模式

  • HandlerInterceptor:请求拦截器
  • Filter:过滤器链
  • ViewResolver:视图解析器链

4.3 Spring Security中的装饰器模式

  • AuthenticationProvider:认证提供者链
  • AccessDecisionVoter:访问决策投票器链

5. 相关源码解读

5.1 Java I/O流中的装饰器模式

// 抽象组件
public abstract class InputStream {public abstract int read() throws IOException;// 其他方法...
}// 具体组件
public class FileInputStream extends InputStream {@Overridepublic int read() throws IOException {// 从文件读取数据}
}// 抽象装饰器
public class FilterInputStream extends InputStream {protected volatile InputStream in;protected FilterInputStream(InputStream in) {this.in = in;}@Overridepublic int read() throws IOException {return in.read();}
}// 具体装饰器
public class BufferedInputStream extends FilterInputStream {private byte[] buf;private int count;private int pos;public BufferedInputStream(InputStream in) {super(in);buf = new byte[8192];}@Overridepublic int read() throws IOException {if (pos >= count) {fill();if (pos >= count)return -1;}return buf[pos++] & 0xff;}
}

5.2 Spring AOP源码分析

// 核心接口
public interface AopProxy {Object getProxy();Object getProxy(ClassLoader classLoader);
}// JDK动态代理实现
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler {private final AdvisedSupport advised;@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 获取拦截器链List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);if (chain.isEmpty()) {// 直接调用目标方法return AopUtils.invokeJoinpointUsingReflection(target, method, args);} else {// 创建方法调用链ReflectiveMethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);return invocation.proceed();}}
}

6. 面试高频点

6.1 基础概念

  • Q: 装饰器模式与代理模式的区别?
  • A: 装饰器模式关注功能的增强,代理模式关注访问控制

6.2 设计原则

  • Q: 装饰器模式体现了哪些设计原则?
  • A: 开闭原则、单一职责原则、组合优于继承

6.3 实际应用

  • Q: 在Spring中如何实现装饰器模式?
  • A: 通过AOP、拦截器、过滤器等机制

6.4 性能考虑

  • Q: 装饰器模式对性能有什么影响?
  • A: 多层装饰器会增加方法调用栈深度,需要权衡功能与性能

6.5 代码实现

  • Q: 如何实现一个缓存装饰器?
  • A: 实现目标接口,持有目标对象引用,添加缓存逻辑

7. 学习途径

7.1 理论学习

  1. 设计模式书籍

    • 《设计模式:可复用面向对象软件的基础》
    • 《Head First设计模式》
    • 《Java设计模式》
  2. 在线资源

    • 菜鸟教程设计模式章节
    • 慕课网设计模式课程
    • B站相关视频教程

7.2 实践学习

  1. 代码实现

    • 实现简单的装饰器模式示例
    • 分析Java I/O流的装饰器实现
    • 研究Spring AOP的装饰器应用
  2. 项目应用

    • 在项目中应用装饰器模式
    • 实现日志装饰器
    • 实现缓存装饰器

7.3 源码学习

  1. Java源码

    • java.io包中的装饰器实现
    • java.util.Collections中的装饰器方法
  2. Spring源码

    • AOP相关源码
    • MVC拦截器源码
    • Security过滤器源码

7.4 进阶学习

  1. 框架应用

    • Spring Boot中的装饰器应用
    • MyBatis中的装饰器模式
    • Dubbo中的装饰器应用
  2. 性能优化

    • 装饰器模式的性能优化
    • 代理对象的缓存策略
    • 方法调用的性能分析

8. 总结

装饰器模式是一种非常实用的设计模式,它通过组合的方式实现了功能的动态扩展,避免了继承的复杂性。在Spring框架中,装饰器模式被广泛应用,特别是在AOP、MVC、Security等模块中。

掌握装饰器模式不仅有助于理解框架的设计思想,还能在实际开发中提供更好的解决方案。通过理论学习、实践应用和源码分析,可以深入理解装饰器模式的精髓,并在面试和实际工作中灵活运用。


文章转载自:

http://zNbtMWwq.tkzrh.cn
http://Ic2lTYsq.tkzrh.cn
http://nltDUpA1.tkzrh.cn
http://K0OOhPCb.tkzrh.cn
http://HlvYqw6c.tkzrh.cn
http://95vk4ELY.tkzrh.cn
http://cetSnfBX.tkzrh.cn
http://8aTxEpbD.tkzrh.cn
http://1lJEIdTd.tkzrh.cn
http://a4k2YV9w.tkzrh.cn
http://lCo7Qxff.tkzrh.cn
http://hp7UwRWg.tkzrh.cn
http://PJgOA22m.tkzrh.cn
http://3ItBqyuU.tkzrh.cn
http://Dnb0xhuo.tkzrh.cn
http://lTicUuja.tkzrh.cn
http://Ktey165W.tkzrh.cn
http://EBScfcsS.tkzrh.cn
http://ejgwSObo.tkzrh.cn
http://XqxfqX0r.tkzrh.cn
http://6Z0TgBjz.tkzrh.cn
http://dENSElIG.tkzrh.cn
http://xiTHXOzW.tkzrh.cn
http://Z5XaHFaV.tkzrh.cn
http://dCfzIobO.tkzrh.cn
http://fNriNs5s.tkzrh.cn
http://l8jPBdZv.tkzrh.cn
http://5XNDvxuv.tkzrh.cn
http://vifrgiKB.tkzrh.cn
http://RosR3C2y.tkzrh.cn
http://www.dtcms.com/a/383776.html

相关文章:

  • 对AQS的详解
  • 实验-基本ACL
  • 开始 ComfyUI 的 AI 绘图之旅-SDXL文生图和图生图(全网首发,官网都没有更新)(十四)
  • Java可用打印数组方法5中+常用变量转字符串方法
  • ssh远程连接服务器到vscode上“连接失败”
  • SpringBoot -原理篇
  • 设计模式——结构型模式
  • I.MX6ULL时钟(clock)与定时器(EPITGPT)
  • STM32_06_Systick定时器
  • 用 Java 学会 Protocol Buffers从 0 到 1 的完整实战
  • 237.删除链表中的节点
  • 【Vue2手录14】导航守卫
  • Qt如何读写xml文件,几种方式对比,读写xml的Demo工程
  • 子网划分专项训练-1,eNSP实验,vlan/dhcp,IP规划
  • 云原生改造实战:Spring Boot 应用的 Kubernetes 迁移全指南
  • 看门狗的驱动原理
  • [论文阅读] 人工智能 + 软件工程 | 大语言模型驱动的多来源漏洞影响库识别研究解析
  • 【前缀和+哈希表】P3131 [USACO16JAN] Subsequences Summing to Sevens S
  • 05.【Linux系统编程】进程(进程概念、进程状态(注意僵尸和孤儿)、进程优先级、进程切换和调度)
  • 【从零开始java学习|小结】记录学习和编程中的问题
  • 图像拼接案例,抠图案例
  • 分层解耦讲解
  • 安装Hadoop中遇到的一些问题和解决
  • 音视频-色域
  • 返利软件的分布式缓存架构:Redis集群在高并发场景下的优化策略
  • 如何让知识上传与查询更便捷
  • set/multiset容器
  • 区块链:搭建简单Fabric网络并调用智能合约
  • Keepalived的详细实操安装流程及其配置文件选项的详解
  • windows下,podman迁移镜像文件位置