一、模式哲学与设计原理
1.1 模式本质
装饰器模式(Decorator Pattern)是一种结构型设计模式,它允许动态地向对象添加新的功能。装饰器模式提供了比继承更灵活的功能扩展方式。
1.2 核心思想
- 动态扩展:运行时添加功能,无需修改原有代码
- 组合替代继承:通过组合而非继承来扩展功能
- 透明包装:装饰对象与被装饰对象具有相同接口
- 层次装饰:支持多层嵌套装饰
1.3 设计原则体现
- 开闭原则:对扩展开放,对修改关闭
- 单一职责原则:每个装饰器只负责一个功能扩展
- 合成复用原则:优先使用组合而非继承
- 里氏替换原则:装饰器可替代原始对象
二、Java源代码实现
2.1 基本实现
抽象组件接口
/**
* 抽象组件接口
* 定义被装饰对象的基本操作
*/
public interface DataSource {
/**
* 写入数据
*/
void writeData(String data);
/**
* 读取数据
*/
String readData();
/**
* 获取数据源类型
*/
String getType();
/**
* 获取配置信息
*/
Map<String, Object> getConfig();
}
具体组件实现
/**
* 具体组件 - 文件数据源
*/
public class FileDataSource implements DataSource {
private final String filename;
private final Map<String, Object> config;
public FileDataSource(String filename) {
this.filename = filename;
this.config = new HashMap<>();
config.put("type", "file");
config.put("filename", filename);
config.put("encoding", "UTF-8");
}
@Override
public void writeData(String data) {
try (FileWriter writer = new FileWriter(filename)) {
writer.write(data);
System.out.println("写入数据到文件: " + filename);
} catch (IOException e) {
throw new RuntimeException("写入文件失败", e);
}
}
@Override
public String readData() {
try {
return new String(Files.readAllBytes(Paths.get(filename)));
} catch (IOException e) {
throw new RuntimeException("读取文件失败", e);
}
}
@Override
public String getType() {
return "FileDataSource";
}
@Override
public Map<String, Object> getConfig() {
return new HashMap<>(config);
}
}
/**
* 具体组件 - 网络数据源
*/
public class NetworkDataSource implements DataSource {
private final String url;
private final Map<String, Object> config;
public NetworkDataSource(String url) {
this.url = url;
this.config = new HashMap<>();
config.put("type", "network");
config.put("url", url);
config.put("timeout", 5000);
}
@Override
public void writeData(String data) {
// 模拟网络写入
System.out.println("通过网络写入数据到: " + url);
System.out.println("数据: " + data.substring(0, Math.min(50, data.length())) + "...");
}
@Override
public String readData() {
// 模拟网络读取
return "从网络读取的数据: " + url;
}
@Override
public String getType() {
return "NetworkDataSource";
}
@Override
public Map<String, Object> getConfig() {
return new HashMap<>(config);
}
}
抽象装饰器
/**
* 抽象装饰器
* 实现DataSource接口,并持有DataSource的引用
*/
public abstract class DataSourceDecorator implements DataSource {
protected DataSource wrappedDataSource;
public DataSourceDecorator(DataSource dataSource) {
this.wrappedDataSource = Objects.requireNonNull(dataSource, "数据源不能为空");
}
@Override
public void writeData(String data) {
wrappedDataSource.writeData(data);
}
@Override
public String readData() {
return wrappedDataSource.readData();
}
@Override
public String getType() {
return wrappedDataSource.getType();
}
@Override
public Map<String, Object> getConfig() {
return wrappedDataSource.getConfig();
}
/**
* 获取被包装的原始数据源
*/
public DataSource getWrappedDataSource() {
return wrappedDataSource;
}
/**
* 获取装饰链
*/
public List<String> getDecoratorChain() {
List<String> chain = new ArrayList<>();
chain.add(this.getClass().getSimpleName());
if (wrappedDataSource instanceof DataSourceDecorator) {
chain.addAll(((DataSourceDecorator) wrappedDataSource).getDecoratorChain());
} else {
chain.add(wrappedDataSource.getClass().getSimpleName());
}
return chain;
}
}
具体装饰器实现
加密装饰器
/**
* 加密装饰器
*/
public class EncryptionDecorator extends DataSourceDecorator {
private final EncryptionAlgorithm algorithm;
private final String encryptionKey;
public EncryptionDecorator(DataSource dataSource) {
this(dataSource, EncryptionAlgorithm.AES, "default-key");
}
public EncryptionDecorator(DataSource dataSource, EncryptionAlgorithm algorithm, String key) {
super(dataSource);
this.algorithm = algorithm;
this.encryptionKey = key;
}
@Override
public void writeData(String data) {
System.out.println("加密装饰器: 对数据进行加密 (" + algorithm + ")");
String encryptedData = encrypt(data);
super.writeData(encryptedData);
}
@Override
public String readData() {
String encryptedData = super.readData();
System.out.println("加密装饰器: 对数据进行解密 (" + algorithm + ")");
return decrypt(encryptedData);
}
@Override
public String getType() {
return "EncryptionDecorator[" + super.getType() + "]";
}
@Override
public Map<String, Object> getConfig() {
Map<String, Object> config = new HashMap<>(super.getConfig());
config.put("encryptionAlgorithm", algorithm.name());
config.put("encryptionEnabled", true);
return config;
}
private String encrypt(String data) {
// 模拟加密
return "ENCRYPTED[" + algorithm + "]{" + data + "}";
}
private String decrypt(String data) {
// 模拟解密
if (data.startsWith("ENCRYPTED[")) {
int end = data.indexOf("]{");
if (end > 0) {
return data.substring(end + 2, data.length() - 1);
}
}
return data;
}
public enum EncryptionAlgorithm {
AES, DES, RSA, BLOWFISH
}
}
压缩装饰器
/**
* 压缩装饰器
*/
public class CompressionDecorator extends DataSourceDecorator {
private final CompressionAlgorithm algorithm;
private final int compressionLevel;
public CompressionDecorator(DataSource dataSource) {
this(dataSource, CompressionAlgorithm.GZIP, 6);
}
public CompressionDecorator(DataSource dataSource, CompressionAlgorithm algorithm, int level) {
super(dataSource);
this.algorithm = algorithm;
this.compressionLevel = Math.max(1, Math.min(9, level));
}
@Override
public void writeData(String data) {
System.out.println("压缩装饰器: 对数据进行压缩 (" + algorithm + ", 级别: " + compressionLevel + ")");
String compressedData = compress(data);
long originalSize = data.length();
long compressedSize = compressedData.length();
double ratio = (double) compressedSize / originalSize * 100;
System.out.printf("压缩率: %.2f%% (原始: %d, 压缩后: %d)%n", ratio, originalSize, compressedSize);
super.writeData(compressedData);
}
@Override
public String readData() {
String compressedData = super.readData();
System.out.println("压缩装饰器: 对数据进行解压 (" + algorithm + ")");
return decompress(compressedData);
}
@Override
public String getType() {
return "CompressionDecorator[" + super.getType() + "]";
}
@Override
public Map<String, Object> getConfig() {
Map<String, Object> config = new HashMap<>(super.getConfig());
config.put("compressionAlgorithm", algorithm.name());
config.put("compressionLevel", compressionLevel);
config.put("compressionEnabled", true);
return config;
}
private String compress(String data) {
// 模拟压缩
return "COMPRESSED[" + algorithm + ":" + compressionLevel + "]{" + data + "}";
}
private String decompress(String data) {
// 模拟解压
if (data.startsWith("COMPRESSED[")) {
int end = data.indexOf("]{");
if (end > 0) {
return data.substring(end + 2, data.length() - 1);
}
}
return data;
}
public enum CompressionAlgorithm {
GZIP, ZIP, DEFLATE, BZIP2
}
}
日志装饰器
/**
* 日志装饰器
*/
public class LoggingDecorator extends DataSourceDecorator {
private final Logger logger;
private final boolean logDetails;
public LoggingDecorator(DataSource dataSource) {
this(dataSource, LoggerFactory.getLogger(LoggingDecorator.class), true);
}
public LoggingDecorator(DataSource dataSource, Logger logger, boolean logDetails) {
super(dataSource);
this.logger = logger;
this.logDetails = logDetails;
}
@Override
public void writeData(String data) {
long startTime = System.currentTimeMillis();
try {
logger.info("开始写入数据");
if (logDetails) {
logger.debug("写入数据长度: {}", data.length());
logger.debug("数据预览: {}", data.substring(0, Math.min(100, data.length())));
}
super.writeData(data);
long endTime = System.currentTimeMillis();
logger.info("数据写入完成,耗时: {}ms", endTime - startTime);
} catch (Exception e) {
logger.error("数据写入失败", e);
throw e;
}
}
@Override
public String readData() {
long startTime = System.currentTimeMillis();
try {
logger.info("开始读取数据");
String data = super.readData();
long endTime = System.currentTimeMillis();
logger.info("数据读取完成,耗时: {}ms", endTime - startTime);
if (logDetails) {
logger.debug("读取数据长度: {}", data.length());
logger.debug("数据预览: {}", data.substring(0, Math.min(100, data.length())));
}
return data;
} catch (Exception e) {
logger.error("数据读取失败", e);
throw e;
}
}
@Override
public String getType() {
return "LoggingDecorator[" + super.getType() + "]";
}
@Override
public Map<String, Object> getConfig() {
Map<String, Object> config = new HashMap<>(super.getConfig());
config.put("loggingEnabled", true);
config.put("logDetails", logDetails);
return config;
}
}
缓存装饰器
/**
* 缓存装饰器
*/
public class CacheDecorator extends DataSourceDecorator {
private final Map<String, CacheEntry> cache = new ConcurrentHashMap<>();
private final long defaultTtl; // 默认过期时间(毫秒)
private final int maxCacheSize;
public CacheDecorator(DataSource dataSource) {
this(dataSource, 5 * 60 * 1000, 1000); // 5分钟过期,最大缓存1000条
}
public CacheDecorator(DataSource dataSource, long ttl, int maxSize) {
super(dataSource);
this.defaultTtl = ttl;
this.maxCacheSize = maxSize;
// 启动清理线程
startCleanupThread();
}
@Override
public void writeData(String data) {
// 写入时清除相关缓存
clearCache();
super.writeData(data);
}
@Override
public String readData() {
String cacheKey = generateCacheKey();
// 检查缓存
CacheEntry entry = cache.get(cacheKey);
if (entry != null && !entry.isExpired()) {
System.out.println("缓存装饰器: 从缓存读取数据");
entry.accessCount++;
entry.lastAccessTime = System.currentTimeMillis();
return entry.data;
}
// 缓存未命中,从底层读取
String data = super.readData();
// 放入缓存
cache.put(cacheKey, new CacheEntry(data, defaultTtl));
// 检查缓存大小
if (cache.size() > maxCacheSize) {
evictOldestEntries();
}
return data;
}
@Override
public String getType() {
return "CacheDecorator[" + super.getType() + "]";
}
@Override
public Map<String, Object> getConfig() {
Map<String, Object> config = new HashMap<>(super.getConfig());
config.put("cachingEnabled", true);
config.put("defaultTtl", defaultTtl);
config.put("maxCacheSize", maxCacheSize);
config.put("currentCacheSize", cache.size());
return config;
}
/**
* 清除缓存
*/
public void clearCache() {
cache.clear();
System.out.println("缓存装饰器: 缓存已清除");
}
/**
* 获取缓存统计信息
*/
public CacheStats getCacheStats() {
int totalEntries = cache.size();
int expiredEntries = 0;
int totalHits = 0;
long totalSize = 0;
for (CacheEntry entry : cache.values()) {
if (entry.isExpired()) {
expiredEntries++;
}
totalHits += entry.accessCount;
totalSize += entry.data.length();
}
return new CacheStats(totalEntries, expiredEntries, totalHits, totalSize);
}
private String generateCacheKey() {
return "read:" + System.identityHashCode(wrappedDataSource);
}
private void evictOldestEntries() {
List<Map.Entry<String, CacheEntry>> entries = new ArrayList<>(cache.entrySet());
entries.sort((a, b) -> Long.compare(a.getValue().lastAccessTime, b.getValue().lastAccessTime));
int toRemove = cache.size() - maxCacheSize;
for (int i = 0; i < toRemove && i < entries.size(); i++) {
cache.remove(entries.get(i).getKey());
}
}
private void startCleanupThread() {
Thread cleanupThread = new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
try {
Thread.sleep(60 * 1000); // 每分钟清理一次
cleanupExpiredEntries();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
}, "cache-cleanup");
cleanupThread.setDaemon(true);
cleanupThread.start();
}
private void cleanupExpiredEntries() {
int expiredCount = 0;
Iterator<Map.Entry<String, CacheEntry>> it = cache.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<String, CacheEntry> entry = it.next();
if (entry.getValue().isExpired()) {
it.remove();
expiredCount++;
}
}
if (expiredCount > 0) {
System.out.println("缓存装饰器: 清理了 " + expiredCount + " 个过期条目");
}
}
/**
* 缓存条目
*/
private static class CacheEntry {
final String data;
final long creationTime;
final long ttl;
long lastAccessTime;
int accessCount;
CacheEntry(String data, long ttl) {
this.data = data;
this.creationTime = System.currentTimeMillis();
this.ttl = ttl;
this.lastAccessTime = creationTime;
this.accessCount = 1;
}
boolean isExpired() {
return System.currentTimeMillis() > creationTime + ttl;
}
}
/**
* 缓存统计信息
*/
public static class CacheStats {
public final int totalEntries;
public final int expiredEntries;
public final int totalHits;
public final long totalSize;
public CacheStats(int totalEntries, int expiredEntries, int totalHits, long totalSize) {
this.totalEntries = totalEntries;
this.expiredEntries = expiredEntries;
this.totalHits = totalHits;
this.totalSize = totalSize;
}
@Override
public String toString() {
return String.format("缓存统计: 总条目=%d, 过期条目=%d, 总命中数=%d, 总大小=%d bytes",
totalEntries, expiredEntries, totalHits, totalSize);
}
}
}
验证装饰器
/**
* 验证装饰器
*/
public class ValidationDecorator extends DataSourceDecorator {
private final List<Validator> validators;
public ValidationDecorator(DataSource dataSource) {
super(dataSource);
this.validators = new ArrayList<>();
// 添加默认验证器
validators.add(new LengthValidator(1, 1024 * 1024)); // 1字节到1MB
validators.add(new ContentValidator());
}
public ValidationDecorator(DataSource dataSource, List<Validator> validators) {
super(dataSource);
this.validators = new ArrayList<>(validators);
}
@Override
public void writeData(String data) {
// 验证数据
for (Validator validator : validators) {
validator.validate(data);
}
System.out.println("验证装饰器: 数据验证通过");
super.writeData(data);
}
@Override
public String getType() {
return "ValidationDecorator[" + super.getType() + "]";
}
@Override
public Map<String, Object> getConfig() {
Map<String, Object> config = new HashMap<>(super.getConfig());
config.put("validationEnabled", true);
config.put("validatorCount", validators.size());
return config;
}
/**
* 添加验证器
*/
public void addValidator(Validator validator) {
validators.add(validator);
}
/**
* 验证器接口
*/
public interface Validator {
void validate(String data) throws ValidationException;
}
/**
* 长度验证器
*/
public static class LengthValidator implements Validator {
private final int minLength;
private final int maxLength;
public LengthValidator(int minLength, int maxLength) {
this.minLength = minLength;
this.maxLength = maxLength;
}
@Override
public void validate(String data) {
int length = data.length();
if (length < minLength) {
throw new ValidationException("数据长度过短: " + length + " < " + minLength);
}
if (length > maxLength) {
throw new ValidationException("数据长度过长: " + length + " > " + maxLength);
}
}
}
/**
* 内容验证器
*/
public static class ContentValidator implements Validator {
@Override
public void validate(String data) {
// 检查空数据
if (data == null || data.trim().isEmpty()) {
throw new ValidationException("数据不能为空");
}
// 检查非法字符
if (data.contains("\0")) {
throw new ValidationException("数据包含空字符");
}
// 这里可以添加更多的内容验证规则
}
}
/**
* 验证异常
*/
public static class ValidationException extends RuntimeException {
public ValidationException(String message) {
super(message);
}
}
}
监控装饰器
/**
* 监控装饰器
*/
public class MonitoringDecorator extends DataSourceDecorator {
private final MetricsCollector metricsCollector;
private final boolean enablePerformanceMetrics;
public MonitoringDecorator(DataSource dataSource) {
this(dataSource, new DefaultMetricsCollector(), true);
}
public MonitoringDecorator(DataSource dataSource, MetricsCollector collector, boolean enablePerformance) {
super(dataSource);
this.metricsCollector = collector;
this.enablePerformanceMetrics = enablePerformance;
}
@Override
public void writeData(String data) {
long startTime = enablePerformanceMetrics ? System.nanoTime() : 0;
try {
super.writeData(data);
metricsCollector.recordSuccess("write", data.length());
} catch (Exception e) {
metricsCollector.recordError("write", e);
throw e;
} finally {
if (enablePerformanceMetrics) {
long duration = System.nanoTime() - startTime;
metricsCollector.recordLatency("write", duration);
}
}
}
@Override
public String readData() {
long startTime = enablePerformanceMetrics ? System.nanoTime() : 0;
try {
String data = super.readData();
metricsCollector.recordSuccess("read", data.length());
return data;
} catch (Exception e) {
metricsCollector.recordError("read", e);
throw e;
} finally {
if (enablePerformanceMetrics) {
long duration = System.nanoTime() - startTime;
metricsCollector.recordLatency("read", duration);
}
}
}
@Override
public String getType() {
return "MonitoringDecorator[" + super.getType() + "]";
}
@Override
public Map<String, Object> getConfig() {
Map<String, Object> config = new HashMap<>(super.getConfig());
config.put("monitoringEnabled", true);
config.put("performanceMetricsEnabled", enablePerformanceMetrics);
return config;
}
/**
* 获取监控指标
*/
public Metrics getMetrics() {
return metricsCollector.getMetrics();
}
/**
* 指标收集器接口
*/
public interface MetricsCollector {
void recordSuccess(String operation, int dataSize);
void recordError(String operation, Exception error);
void recordLatency(String operation, long nanoseconds);
Metrics getMetrics();
}
/**
* 默认指标收集器
*/
public static class DefaultMetricsCollector implements MetricsCollector {
private final Map<String, OperationMetrics> metricsMap = new ConcurrentHashMap<>();
@Override
public void recordSuccess(String operation, int dataSize) {
OperationMetrics metrics = getOrCreateMetrics(operation);
metrics.successCount++;
metrics.totalDataSize += dataSize;
}
@Override
public void recordError(String operation, Exception error) {
OperationMetrics metrics = getOrCreateMetrics(operation);
metrics.errorCount++;
metrics.lastError = error.getClass().getSimpleName();
}
@Override
public void recordLatency(String operation, long nanoseconds) {
OperationMetrics metrics = getOrCreateMetrics(operation);
metrics.totalLatency += nanoseconds;
metrics.callCount++;
metrics.maxLatency = Math.max(metrics.maxLatency, nanoseconds);
metrics.minLatency = Math.min(metrics.minLatency, nanoseconds);
}
@Override
public Metrics getMetrics() {
return new Metrics(new HashMap<>(metricsMap));
}
private OperationMetrics getOrCreateMetrics(String operation) {
return metricsMap.computeIfAbsent(operation, k -> new OperationMetrics());
}
}
/**
* 操作指标
*/
public static class OperationMetrics {
public long callCount = 0;
public long successCount = 0;
public long errorCount = 0;
public long totalDataSize = 0;
public long totalLatency = 0;
public long maxLatency = 0;
public long minLatency = Long.MAX_VALUE;
public String lastError = null;
public double getSuccessRate() {
return callCount > 0 ? (double) successCount / callCount * 100 : 0;
}
public double getAverageLatencyMs() {
return callCount > 0 ? (totalLatency / 1_000_000.0) / callCount : 0;
}
public double getAverageDataSize() {
return callCount > 0 ? (double) totalDataSize / callCount : 0;
}
}
/**
* 指标汇总
*/
public static class Metrics {
private final Map<String, OperationMetrics> metrics;
public Metrics(Map<String, OperationMetrics> metrics) {
this.metrics = metrics;
}
public void printMetrics() {
System.out.println("=== 监控指标 ===");
for (Map.Entry<String, OperationMetrics> entry : metrics.entrySet()) {
String operation = entry.getKey();
OperationMetrics opMetrics = entry.getValue();
System.out.printf("操作: %s%n", operation);
System.out.printf(" 调用次数: %d%n", opMetrics.callCount);
System.out.printf(" 成功率: %.2f%%%n", opMetrics.getSuccessRate());
System.out.printf(" 平均延迟: %.2fms%n", opMetrics.getAverageLatencyMs());
System.out.printf(" 最大延迟: %.2fms%n", opMetrics.maxLatency / 1_000_000.0);
System.out.printf(" 最小延迟: %.2fms%n",
opMetrics.minLatency == Long.MAX_VALUE ? 0 : opMetrics.minLatency / 1_000_000.0);
System.out.printf(" 平均数据大小: %.2f bytes%n", opMetrics.getAverageDataSize());
if (opMetrics.lastError != null) {
System.out.printf(" 最后错误: %s%n", opMetrics.lastError);
}
System.out.println();
}
}
}
}
2.2 客户端使用示例
/**
* 装饰器模式客户端示例
*/
public class DecoratorClient {
public static void main(String[] args) {
System.out.println("=== 装饰器模式示例 ===\n");
// 示例1:基本使用
example1();
System.out.println("\n---\n");
// 示例2:多层装饰
example2();
System.out.println("\n---\n");
// 示例3:动态组合装饰器
example3();
System.out.println("\n---\n");
// 示例4:监控示例
example4();
}
/**
* 示例1:基本使用 - 单个装饰器
*/
private static void example1() {
System.out.println("示例1:基本使用");
// 创建基础数据源
DataSource fileSource = new FileDataSource("test.txt");
// 添加加密装饰
DataSource encryptedSource = new EncryptionDecorator(fileSource);
// 使用装饰后的数据源
String data = "这是一段需要加密的敏感数据";
encryptedSource.writeData(data);
String readData = encryptedSource.readData();
System.out.println("读取的数据: " + readData);
// 查看装饰链
List<String> chain = ((DataSourceDecorator) encryptedSource).getDecoratorChain();
System.out.println("装饰链: " + chain);
}
/**
* 示例2:多层装饰 - 加密+压缩+日志
*/
private static void example2() {
System.out.println("示例2:多层装饰");
// 创建基础数据源
DataSource source = new FileDataSource("data.bin");
// 多层装饰
source = new EncryptionDecorator(source, EncryptionDecorator.EncryptionAlgorithm.AES, "secret-key");
source = new CompressionDecorator(source, CompressionDecorator.CompressionAlgorithm.GZIP, 9);
source = new LoggingDecorator(source);
// 生成测试数据
StringBuilder testData = new StringBuilder();
for (int i = 0; i < 1000; i++) {
testData.append("这是一些测试数据,用于演示压缩和加密功能。").append(i).append("\n");
}
// 写入数据
source.writeData(testData.toString());
// 读取数据
String result = source.readData();
System.out.println("读取数据长度: " + result.length());
// 查看配置
Map<String, Object> config = source.getConfig();
System.out.println("最终配置: " + config);
}
/**
* 示例3:动态组合装饰器
*/
private static void example3() {
System.out.println("示例3:动态组合装饰器");
// 根据需求动态组合装饰器
DataSource source = new NetworkDataSource("http://api.example.com/data");
// 根据配置添加装饰器
boolean enableEncryption = true;
boolean enableCompression = false;
boolean enableCaching = true;
boolean enableValidation = true;
if (enableValidation) {
source = new ValidationDecorator(source);
}
if (enableEncryption) {
source = new EncryptionDecorator(source);
}
if (enableCompression) {
source = new CompressionDecorator(source);
}
if (enableCaching) {
source = new CacheDecorator(source, 60 * 1000, 100); // 1分钟缓存
}
// 测试缓存功能
System.out.println("第一次读取(应该从网络读取):");
String data1 = source.readData();
System.out.println("\n第二次读取(应该从缓存读取):");
String data2 = source.readData();
// 获取缓存统计
if (source instanceof CacheDecorator) {
CacheDecorator.CacheStats stats = ((CacheDecorator) source).getCacheStats();
System.out.println("\n" + stats);
}
}
/**
* 示例4:监控示例
*/
private static void example4() {
System.out.println("示例4:监控装饰器");
DataSource source = new FileDataSource("monitored.txt");
source = new MonitoringDecorator(source);
// 执行多次操作
for (int i = 0; i < 5; i++) {
try {
source.writeData("测试数据 " + i);
source.readData();
// 模拟偶尔的错误
if (i == 2) {
// 测试验证
DataSource validationSource = new ValidationDecorator(source);
try {
validationSource.writeData(""); // 空数据应该失败
} catch (ValidationDecorator.ValidationException e) {
System.out.println("验证错误(预期中): " + e.getMessage());
}
}
} catch (Exception e) {
System.out.println("操作失败: " + e.getMessage());
}
}
// 查看监控指标
if (source instanceof MonitoringDecorator) {
MonitoringDecorator.Metrics metrics = ((MonitoringDecorator) source).getMetrics();
metrics.printMetrics();
}
}
}
/**
* 装饰器工厂
* 用于创建预配置的装饰器组合
*/
public class DataSourceDecoratorFactory {
/**
* 创建安全数据源(加密+验证)
*/
public static DataSource createSecureDataSource(DataSource dataSource) {
return new EncryptionDecorator(
new ValidationDecorator(dataSource)
);
}
/**
* 创建高性能数据源(压缩+缓存)
*/
public static DataSource createHighPerformanceDataSource(DataSource dataSource) {
return new CompressionDecorator(
new CacheDecorator(dataSource, 5 * 60 * 1000, 1000)
);
}
/**
* 创建生产环境数据源(全功能)
*/
public static DataSource createProductionDataSource(DataSource dataSource) {
return new MonitoringDecorator(
new LoggingDecorator(
new EncryptionDecorator(
new CompressionDecorator(
new ValidationDecorator(
new CacheDecorator(dataSource)
)
)
)
)
);
}
/**
* 根据配置文件创建装饰器
*/
public static DataSource createDataSourceFromConfig(DataSource dataSource, Properties config) {
DataSource result = dataSource;
if (Boolean.parseBoolean(config.getProperty("enableValidation", "true"))) {
result = new ValidationDecorator(result);
}
if (Boolean.parseBoolean(config.getProperty("enableEncryption", "false"))) {
String algorithm = config.getProperty("encryptionAlgorithm", "AES");
String key = config.getProperty("encryptionKey", "default-key");
result = new EncryptionDecorator(result,
EncryptionDecorator.EncryptionAlgorithm.valueOf(algorithm), key);
}
if (Boolean.parseBoolean(config.getProperty("enableCompression", "false"))) {
String algorithm = config.getProperty("compressionAlgorithm", "GZIP");
int level = Integer.parseInt(config.getProperty("compressionLevel", "6"));
result = new CompressionDecorator(result,
CompressionDecorator.CompressionAlgorithm.valueOf(algorithm), level);
}
if (Boolean.parseBoolean(config.getProperty("enableCaching", "true"))) {
long ttl = Long.parseLong(config.getProperty("cacheTtl", "300000")); // 5分钟
int maxSize = Integer.parseInt(config.getProperty("cacheMaxSize", "1000"));
result = new CacheDecorator(result, ttl, maxSize);
}
if (Boolean.parseBoolean(config.getProperty("enableLogging", "true"))) {
result = new LoggingDecorator(result);
}
if (Boolean.parseBoolean(config.getProperty("enableMonitoring", "true"))) {
result = new MonitoringDecorator(result);
}
return result;
}
}
三、应用场景深度解析
3.1 I/O流处理
/**
* Java I/O流是装饰器模式的经典应用
*/
public class IOStreamExample {
public static void main(String[] args) throws IOException {
// FileInputStream 是具体组件
FileInputStream fileInputStream = new FileInputStream("input.txt");
// BufferedInputStream 是装饰器
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
// DataInputStream 是另一个装饰器
DataInputStream dataInputStream = new DataInputStream(bufferedInputStream);
// 可以继续装饰
PushbackInputStream pushbackInputStream = new PushbackInputStream(dataInputStream);
// 使用装饰后的流
byte[] buffer = new byte[1024];
int bytesRead = pushbackInputStream.read(buffer);
pushbackInputStream.close();
}
}
/**
* 自定义I/O装饰器示例
*/
public class CustomInputStream extends FilterInputStream {
private final byte key;
private int position = 0;
protected CustomInputStream(InputStream in, byte key) {
super(in);
this.key = key;
}
@Override
public int read() throws IOException {
int data = super.read();
if (data == -1) {
return -1;
}
// 简单的异或加密
return data ^ key ^ (position++ % 256);
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
int bytesRead = super.read(b, off, len);
for (int i = 0; i < bytesRead; i++) {
b[off + i] = (byte) (b[off + i] ^ key ^ ((position + i) % 256));
}
position += bytesRead;
return bytesRead;
}
}
3.2 Web请求处理
/**
* Servlet过滤器是装饰器模式的典型应用
*/
public class WebFilterExample {
// 模拟HttpServletRequest
public interface HttpServletRequest {
String getParameter(String name);
// 其他方法...
}
// 模拟HttpServletResponse
public interface HttpServletResponse {
// 响应方法...
}
// 过滤器接口
public interface Filter {
void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain);
}
// 过滤器链
public interface FilterChain {
void doFilter(HttpServletRequest request, HttpServletResponse response);
}
// 具体过滤器实现
public static class AuthenticationFilter implements Filter {
@Override
public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) {
System.out.println("认证过滤器: 检查用户认证");
// 检查认证逻辑...
chain.doFilter(request, response);
}
}
public static class LoggingFilter implements Filter {
@Override
public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) {
long startTime = System.currentTimeMillis();
System.out.println("日志过滤器: 请求开始");
chain.doFilter(request, response);
long duration = System.currentTimeMillis() - startTime;
System.out.println("日志过滤器: 请求完成,耗时 " + duration + "ms");
}
}
public static class CompressionFilter implements Filter {
@Override
public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) {
System.out.println("压缩过滤器: 压缩响应数据");
chain.doFilter(request, response);
System.out.println("压缩过滤器: 响应已压缩");
}
}
// 过滤器链实现
public static class StandardFilterChain implements FilterChain {
private final List<Filter> filters = new ArrayList<>();
private int index = 0;
private final Runnable target; // 最终目标(如Servlet)
public StandardFilterChain(List<Filter> filters, Runnable target) {
this.filters.addAll(filters);
this.target = target;
}
@Override
public void doFilter(HttpServletRequest request, HttpServletResponse response) {
if (index < filters.size()) {
Filter filter = filters.get(index++);
filter.doFilter(request, response, this);
} else {
target.run(); // 执行最终目标
}
}
}
}
3.3 权限控制
/**
* 基于装饰器的权限控制系统
*/
public class SecurityExample {
// 操作接口
public interface Operation {
void execute();
boolean hasPermission(String user);
}
// 具体操作
public static class DeleteOperation implements Operation {
@Override
public void execute() {
System.out.println("执行删除操作");
}
@Override
public boolean hasPermission(String user) {
return true; // 基础权限检查
}
}
// 权限装饰器
public static class PermissionDecorator implements Operation {
private final Operation operation;
private final String requiredRole;
public PermissionDecorator(Operation operation, String requiredRole) {
this.operation = operation;
this.requiredRole = requiredRole;
}
@Override
public void execute() {
// 在实际应用中,这里会检查当前用户的角色
System.out.println("检查权限: 需要角色 " + requiredRole);
operation.execute();
}
@Override
public boolean hasPermission(String user) {
// 模拟权限检查
return operation.hasPermission(user) && checkUserRole(user, requiredRole);
}
private boolean checkUserRole(String user, String requiredRole) {
// 模拟角色检查逻辑
return "admin".equals(user) || requiredRole.equals("user");
}
}
// 审计装饰器
public static class AuditDecorator implements Operation {
private final Operation operation;
public AuditDecorator(Operation operation) {
this.operation = operation;
}
@Override
public void execute() {
long startTime = System.currentTimeMillis();
String user = getCurrentUser(); // 获取当前用户
System.out.println("审计日志: 用户 " + user + " 开始执行操作");
try {
operation.execute();
System.out.println("审计日志: 操作执行成功");
} catch (Exception e) {
System.out.println("审计日志: 操作执行失败 - " + e.getMessage());
throw e;
} finally {
long duration = System.currentTimeMillis() - startTime;
System.out.println("审计日志: 操作耗时 " + duration + "ms");
}
}
@Override
public boolean hasPermission(String user) {
return operation.hasPermission(user);
}
private String getCurrentUser() {
// 模拟获取当前用户
return "current-user";
}
}
}
3.4 缓存系统
/**
* 装饰器模式在缓存系统中的应用
*/
public class CacheExample {
// 数据访问接口
public interface UserRepository {
User findById(String id);
void save(User user);
}
// 具体实现
public static class DatabaseUserRepository implements UserRepository {
@Override
public User findById(String id) {
System.out.println("从数据库查询用户: " + id);
// 模拟数据库查询
return new User(id, "用户" + id);
}
@Override
public void save(User user) {
System.out.println("保存用户到数据库: " + user.getId());
}
}
// 缓存装饰器
public static class CachingUserRepository implements UserRepository {
private final UserRepository repository;
private final Map<String, User> cache = new ConcurrentHashMap<>();
private final Map<String, Long> cacheTimestamps = new ConcurrentHashMap<>();
private final long ttl; // 缓存存活时间(毫秒)
public CachingUserRepository(UserRepository repository, long ttl) {
this.repository = repository;
this.ttl = ttl;
}
@Override
public User findById(String id) {
// 检查缓存
User cachedUser = cache.get(id);
Long timestamp = cacheTimestamps.get(id);
if (cachedUser != null && timestamp != null) {
if (System.currentTimeMillis() - timestamp < ttl) {
System.out.println("从缓存获取用户: " + id);
return cachedUser;
} else {
// 缓存过期
cache.remove(id);
cacheTimestamps.remove(id);
}
}
// 缓存未命中,从底层获取
User user = repository.findById(id);
// 更新缓存
cache.put(id, user);
cacheTimestamps.put(id, System.currentTimeMillis());
return user;
}
@Override
public void save(User user) {
// 保存到数据库
repository.save(user);
// 更新缓存
cache.put(user.getId(), user);
cacheTimestamps.put(user.getId(), System.currentTimeMillis());
}
public void clearCache() {
cache.clear();
cacheTimestamps.clear();
}
public int getCacheSize() {
return cache.size();
}
}
// 监控装饰器
public static class MonitoringUserRepository implements UserRepository {
private final UserRepository repository;
private int hitCount = 0;
private int missCount = 0;
public MonitoringUserRepository(UserRepository repository) {
this.repository = repository;
}
@Override
public User findById(String id) {
User user = repository.findById(id);
// 判断是否来自缓存
if (repository instanceof CachingUserRepository) {
// 这里简化判断,实际需要更复杂的逻辑
System.out.println("监控: 查询用户 " + id);
}
return user;
}
@Override
public void save(User user) {
repository.save(user);
}
public void printStats() {
System.out.println("缓存统计: 命中=" + hitCount + ", 未命中=" + missCount);
}
}
public static class User {
private final String id;
private final String name;
public User(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() { return id; }
public String getName() { return name; }
}
}
四、优缺点深度分析
4.1 优点详细分析
1. 动态扩展功能
// 运行时动态添加功能
DataSource source = new FileDataSource("data.txt");
// 需要时添加加密
if (needsEncryption) {
source = new EncryptionDecorator(source);
}
// 需要时添加压缩
if (needsCompression) {
source = new CompressionDecorator(source);
}
// 可以任意组合,无需修改原有代码
2. 避免类爆炸
// 不使用装饰器模式,需要大量子类
class EncryptedFileDataSource extends FileDataSource { /* ... */ }
class CompressedFileDataSource extends FileDataSource { /* ... */ }
class EncryptedCompressedFileDataSource extends FileDataSource { /* ... */ }
class LoggedEncryptedFileDataSource extends FileDataSource { /* ... */ }
// 组合爆炸:n个功能需要2^n个子类
// 使用装饰器模式
// 只需要n个装饰器类,可以任意组合
3. 符合开闭原则
// 新增功能只需新增装饰器,无需修改现有代码
public class NewFeatureDecorator extends DataSourceDecorator {
// 实现新功能
@Override
public void writeData(String data) {
// 添加新功能
System.out.println("执行新功能");
super.writeData(data);
}
}
// 现有代码无需修改
DataSource source = new FileDataSource("data.txt");
source = new NewFeatureDecorator(source); // 无缝集成
4. 单一职责原则
// 每个装饰器只负责一个功能
class EncryptionDecorator { // 只负责加密
public void writeData(String data) {
String encrypted = encrypt(data);
super.writeData(encrypted);
}
}
class CompressionDecorator { // 只负责压缩
public void writeData(String data) {
String compressed = compress(data);
super.writeData(compressed);
}
}
class LoggingDecorator { // 只负责日志
public void writeData(String data) {
log("开始写入");
super.writeData(data);
log("写入完成");
}
}
5. 灵活组合
// 可以按需组合装饰器
DataSource createDataSource(boolean encrypt, boolean compress, boolean log) {
DataSource source = new FileDataSource("data.txt");
if (log) {
source = new LoggingDecorator(source);
}
if (encrypt) {
source = new EncryptionDecorator(source);
}
if (compress) {
source = new CompressionDecorator(source);
}
return source;
}
4.2 缺点详细分析
1. 复杂度增加
// 多层装饰导致调用链变深
DataSource source = new LoggingDecorator(
new EncryptionDecorator(
new CompressionDecorator(
new ValidationDecorator(
new FileDataSource("data.txt")
)
)
)
);
// 调用writeData时的调用链:
// LoggingDecorator.writeData()
// -> EncryptionDecorator.writeData()
// -> CompressionDecorator.writeData()
// -> ValidationDecorator.writeData()
// -> FileDataSource.writeData()
2. 调试困难
// 问题定位困难
try {
source.writeData(data);
} catch (Exception e) {
// 很难确定是哪个装饰器出的问题
e.printStackTrace(); // 堆栈跟踪很长
}
// 日志输出混乱
// [LoggingDecorator] 开始写入
// [EncryptionDecorator] 加密数据
// [CompressionDecorator] 压缩数据
// [ValidationDecorator] 验证数据
// [FileDataSource] 写入文件
// [ValidationDecorator] 验证完成
// [CompressionDecorator] 压缩完成
// [EncryptionDecorator] 加密完成
// [LoggingDecorator] 写入完成
3. 实例化复杂
// 多层嵌套实例化
DataSource source = new LoggingDecorator(
new MonitoringDecorator(
new CacheDecorator(
new EncryptionDecorator(
new CompressionDecorator(
new ValidationDecorator(
new FileDataSource("data.txt")
)
),
EncryptionAlgorithm.AES,
"key123"
),
300000,
1000
)
)
);
4. 性能开销
// 每层装饰都有方法调用开销
public class DecoratorWithOverhead extends DataSourceDecorator {
@Override
public void writeData(String data) {
// 装饰器自身的逻辑
doSomethingBefore();
// 调用下一层
super.writeData(data);
// 装饰器自身的逻辑
doSomethingAfter();
}
private void doSomethingBefore() {
// 额外的处理
}
private void doSomethingAfter() {
// 额外的处理
}
}
// 多层装饰时,这些开销会累积
5. 配置管理复杂
// 装饰器的配置管理
public class ConfiguredDecorator extends DataSourceDecorator {
private final Properties config;
public ConfiguredDecorator(DataSource dataSource, Properties config) {
super(dataSource);
this.config = config;
}
@Override
public void writeData(String data) {
if (Boolean.parseBoolean(config.getProperty("enabled", "true"))) {
// 使用配置参数
String mode = config.getProperty("mode", "default");
// ...
}
super.writeData(data);
}
}
// 需要为每个装饰器管理配置
五、使用要点深度解析
5.1 透明性与装饰器顺序
保持接口透明
// 装饰器必须保持与组件相同的接口
public abstract class DataSourceDecorator implements DataSource {
// 必须实现DataSource的所有方法
// 即使只是简单委托给wrappedDataSource
}
// 客户端无需知道是否被装饰
public void processDataSource(DataSource source) {
// 可以处理任何DataSource,无论是否被装饰
source.writeData("data");
String result = source.readData();
}
装饰器顺序的重要性
// 顺序不同,结果不同
DataSource source1 = new FileDataSource("data.txt");
source1 = new EncryptionDecorator(source1);
source1 = new CompressionDecorator(source1);
// 顺序:加密 -> 压缩
// 先加密,再压缩加密后的数据
DataSource source2 = new FileDataSource("data.txt");
source2 = new CompressionDecorator(source2);
source2 = new EncryptionDecorator(source2);
// 顺序:压缩 -> 加密
// 先压缩,再加密压缩后的数据
// 两种顺序产生不同的结果
5.2 避免过度装饰
设置装饰层数限制
public abstract class LimitedDecorator extends DataSourceDecorator {
private static final int MAX_DEPTH = 10;
public LimitedDecorator(DataSource dataSource) {
super(dataSource);
checkDepth();
}
private void checkDepth() {
int depth = calculateDepth();
if (depth > MAX_DEPTH) {
throw new IllegalStateException("装饰层数过多: " + depth);
}
}
private int calculateDepth() {
int depth = 1;
DataSource current = wrappedDataSource;
while (current instanceof DataSourceDecorator) {
depth++;
current = ((DataSourceDecorator) current).getWrappedDataSource();
}
return depth;
}
}
使用工厂方法控制
public class DecoratorFactory {
public static DataSource createOptimizedDataSource(DataSource base) {
// 优化装饰顺序
DataSource result = base;
// 验证应该在最外层
result = new ValidationDecorator(result);
// 然后是加密
result = new EncryptionDecorator(result);
// 接着是压缩
result = new CompressionDecorator(result);
// 缓存应该在加密和压缩之后
result = new CacheDecorator(result);
// 日志和监控在最外层
result = new LoggingDecorator(result);
result = new MonitoringDecorator(result);
return result;
}
}
5.3 性能优化策略
缓存装饰结果
public class CachingDecorator extends DataSourceDecorator {
private final Map<String, String> readCache = new ConcurrentHashMap<>();
private boolean cacheEnabled = true;
@Override
public String readData() {
if (!cacheEnabled) {
return super.readData();
}
String cacheKey = generateCacheKey();
if (readCache.containsKey(cacheKey)) {
return readCache.get(cacheKey);
}
String data = super.readData();
readCache.put(cacheKey, data);
return data;
}
@Override
public void writeData(String data) {
// 写入时清除相关缓存
readCache.clear();
super.writeData(data);
}
private String generateCacheKey() {
// 基于数据源标识生成缓存键
return "read:" + System.identityHashCode(wrappedDataSource);
}
}
延迟初始化
public class LazyDecorator extends DataSourceDecorator {
private volatile DataSource lazyWrapped;
private final Supplier<DataSource> dataSourceSupplier;
public LazyDecorator(Supplier<DataSource> supplier) {
super(null); // 暂时为null
this.dataSourceSupplier = supplier;
}
private DataSource getWrappedDataSource() {
if (lazyWrapped == null) {
synchronized (this) {
if (lazyWrapped == null) {
lazyWrapped = dataSourceSupplier.get();
super.wrappedDataSource = lazyWrapped;
}
}
}
return lazyWrapped;
}
@Override
public void writeData(String data) {
getWrappedDataSource().writeData(data);
}
@Override
public String readData() {
return getWrappedDataSource().readData();
}
}
5.4 错误处理和回滚
事务性装饰器
public class TransactionalDecorator extends DataSourceDecorator {
@Override
public void writeData(String data) {
// 保存原始状态以便回滚
String originalData = null;
try {
originalData = super.readData();
} catch (Exception e) {
// 忽略读取错误
}
try {
super.writeData(data);
} catch (Exception e) {
// 写入失败,尝试回滚
if (originalData != null) {
try {
super.writeData(originalData);
} catch (Exception rollbackException) {
// 回滚失败
throw new RuntimeException("写入失败且回滚也失败", e);
}
}
throw e;
}
}
}
错误恢复装饰器
public class RetryDecorator extends DataSourceDecorator {
private final int maxRetries;
private final long retryDelay;
public RetryDecorator(DataSource dataSource, int maxRetries, long retryDelay) {
super(dataSource);
this.maxRetries = maxRetries;
this.retryDelay = retryDelay;
}
@Override
public void writeData(String data) {
int attempt = 0;
while (true) {
try {
super.writeData(data);
return;
} catch (Exception e) {
attempt++;
if (attempt > maxRetries) {
throw new RuntimeException("操作失败,已达到最大重试次数", e);
}
System.out.println("操作失败,第" + attempt + "次重试");
try {
Thread.sleep(retryDelay);
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw new RuntimeException("重试被中断", e);
}
}
}
}
}
六、与其他模式的关系
6.1 装饰器 vs 适配器
// 装饰器模式:增强功能,保持接口
public class Decorator implements TargetInterface {
private TargetInterface target;
public Decorator(TargetInterface target) {
this.target = target;
}
@Override
public void operation() {
// 添加额外功能
doSomethingExtra();
target.operation();
}
}
// 适配器模式:转换接口,不增强功能
public class Adapter implements TargetInterface {
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
public void operation() {
// 调用适配对象的方法
adaptee.specificOperation();
}
}
6.2 装饰器 vs 代理
// 装饰器模式:动态添加功能
public class Decorator implements Component {
private Component component;
public Decorator(Component component) {
this.component = component;
}
@Override
public void operation() {
// 添加额外功能
component.operation();
}
}
// 代理模式:控制访问
public class Proxy implements Component {
private RealComponent realComponent;
private boolean hasAccess;
public Proxy(boolean hasAccess) {
this.hasAccess = hasAccess;
}
@Override
public void operation() {
if (!hasAccess) {
throw new SecurityException("无访问权限");
}
if (realComponent == null) {
realComponent = new RealComponent(); // 延迟加载
}
realComponent.operation();
}
}
6.3 装饰器 vs 责任链
// 装饰器模式:每个装饰器都执行操作
public class Decorator implements Handler {
private Handler next;
@Override
public void handle(Request request) {
// 1. 执行自己的处理
doSomething(request);
// 2. 传递给下一个装饰器
if (next != null) {
next.handle(request);
}
}
}
// 责任链模式:只有一个处理器处理请求
public class ChainHandler implements Handler {
private Handler next;
@Override
public void handle(Request request) {
if (canHandle(request)) {
// 自己处理
process(request);
} else if (next != null) {
// 传递给下一个
next.handle(request);
} else {
// 无人处理
throw new UnsupportedOperationException();
}
}
}
七、实际应用案例
7.1 Java I/O流
// Java的InputStream/OutputStream是装饰器模式的经典实现
public class JavaIOExample {
public static void main(String[] args) throws IOException {
// FileInputStream是具体组件
FileInputStream fis = new FileInputStream("input.txt");
// BufferedInputStream是装饰器
BufferedInputStream bis = new BufferedInputStream(fis);
// DataInputStream是另一个装饰器
DataInputStream dis = new DataInputStream(bis);
// 可以继续装饰
PushbackInputStream pis = new PushbackInputStream(dis);
// 使用
byte[] buffer = new byte[1024];
int bytes = pis.read(buffer);
pis.close();
}
}
7.2 Java Collections
// Collections工具类中的装饰器方法
public class CollectionsExample {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
// 创建同步列表(装饰器)
List<String> synchronizedList = Collections.synchronizedList(list);
// 创建不可修改列表(装饰器)
List<String> unmodifiableList = Collections.unmodifiableList(list);
// 检查包装
if (unmodifiableList instanceof Collections.UnmodifiableList) {
System.out.println("这是一个不可修改列表装饰器");
}
}
}
7.3 Spring框架
// Spring中的装饰器模式应用
@Configuration
public class SpringExample {
// Spring的AOP是装饰器模式的一种实现
@Bean
@Profile("production")
public DataSource productionDataSource() {
DataSource dataSource = new BasicDataSource();
// 添加监控
dataSource = new MonitoringDecorator(dataSource);
// 添加缓存
dataSource = new CacheDecorator(dataSource);
return dataSource;
}
// Spring的Web过滤器链
@Bean
public FilterRegistrationBean<Filter> loggingFilter() {
FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>();
registration.setFilter(new LoggingFilter());
registration.addUrlPatterns("/*");
registration.setOrder(1);
return registration;
}
public static class LoggingFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// 日志逻辑
chain.doFilter(request, response);
}
}
}
八、最佳实践
8.1 设计建议
- 保持装饰器轻量级:装饰器应该只负责单一功能
- 注意装饰顺序:某些装饰器有顺序依赖
- 避免循环装饰:装饰器不应装饰自身
- 提供配置支持:允许动态启用/禁用装饰器
- 实现适当的接口:确保装饰器透明
8.2 性能优化
- 使用缓存:缓存昂贵的计算结果
- 延迟初始化:需要时才初始化资源
- 批处理:合并多个操作为一个
- 异步处理:非阻塞执行耗时操作
8.3 测试要点
- 测试单个装饰器:确保每个装饰器正确工作
- 测试装饰器组合:测试多个装饰器组合的效果
- 测试装饰顺序:验证不同顺序的结果
- 测试错误处理:确保装饰器能正确处理异常
- 测试性能:验证装饰器不会引入过大开销
九、总结
装饰器模式是一种强大的结构型设计模式,特别适合需要动态、透明地扩展对象功能的场景。
9.1 核心优势
- 动态扩展:运行时添加功能,无需修改源代码
- 灵活组合:可以任意组合多个装饰器
- 符合开闭原则:新增功能不影响现有代码
- 透明性:客户端无需知道对象是否被装饰
9.2 适用场景判断
- ✅ 需要动态、透明地添加功能
- ✅ 功能可以独立组合使用
- ✅ 避免使用子类进行扩展
- ✅ 需要运行时决定功能组合
- ❌ 装饰器之间有强顺序依赖
- ❌ 需要修改组件接口
- ❌ 性能要求极其苛刻
9.3 实现要点
- 定义清晰接口:组件和装饰器实现相同接口
- 保持透明性:装饰器不应改变组件接口
- 控制装饰层数:避免过度装饰导致性能问题
- 注意装饰顺序:某些功能有执行顺序要求
- 提供工厂支持:简化复杂装饰器的创建
装饰器模式是构建灵活、可扩展系统的有效工具,在Java I/O、Web框架、中间件等许多领域都有广泛应用。正确使用装饰器模式可以显著提高代码的可维护性和可扩展性。