以下以 云存储文件上传 场景为例,展示如何通过装饰器模式实现 基础文件上传 + 加密 + 压缩 + 日志记录 的灵活组合,并与传统实现方式对比
装饰器模式实现
1. 核心接口定义
public interface FileUploader {
void upload(String filePath);
}
2. 基础上传实现
@Component
public class BasicFileUploader implements FileUploader {
@Override
public void upload(String filePath) {
System.out.println("[核心逻辑] 上传文件到云存储: " + filePath);
}
}
3. 装饰器抽象类
public abstract class FileUploadDecorator implements FileUploader {
protected final FileUploader wrapped;
public FileUploadDecorator(FileUploader uploader) {
this.wrapped = uploader;
}
@Override
public abstract void upload(String filePath);
}
4. 具体装饰器实现
// 加密装饰器
@Component
public class EncryptUploadDecorator extends FileUploadDecorator {
public EncryptUploadDecorator(FileUploader uploader) {
super(uploader);
}
@Override
public void upload(String filePath) {
String encryptedFile = encrypt(filePath);
wrapped.upload(encryptedFile);
}
private String encrypt(String filePath) {
System.out.println(">>> 加密文件: " + filePath);
return filePath + ".enc";
}
}
// 压缩装饰器
@Component
public class CompressUploadDecorator extends FileUploadDecorator {
public CompressUploadDecorator(FileUploader uploader) {
super(uploader);
}
@Override
public void upload(String filePath) {
String compressedFile = compress(filePath);
wrapped.upload(compressedFile);
}
private String compress(String filePath) {
System.out.println(">>> 压缩文件: " + filePath);
return filePath + ".zip";
}
}
// 日志记录装饰器
@Component
public class LoggingUploadDecorator extends FileUploadDecorator {
public LoggingUploadDecorator(FileUploader uploader) {
super(uploader);
}
@Override
public void upload(String filePath) {
System.out.println("【开始上传】" + LocalDateTime.now());
wrapped.upload(filePath);
System.out.println("【上传完成】" + LocalDateTime.now());
}
}
5. 组合装饰器(通过Spring配置)
@Configuration
public class UploadConfig {
@Bean("secureUploader")
public FileUploader buildSecureUploader(
BasicFileUploader base,
EncryptUploadDecorator encrypt,
CompressUploadDecorator compress) {
// 组合顺序:加密 → 压缩 → 基础上传
return new EncryptUploadDecorator(
new CompressUploadDecorator(base)
);
}
@Bean("fullFeatureUploader")
public FileUploader buildFullFeatureUploader(
BasicFileUploader base,
EncryptUploadDecorator encrypt,
CompressUploadDecorator compress,
LoggingUploadDecorator logging) {
// 组合顺序:日志 → 加密 → 压缩 → 基础上传
return new LoggingUploadDecorator(
new EncryptUploadDecorator(
new CompressUploadDecorator(base)
)
);
}
}
6. 对外暴露接口
@RestController
public class FileController {
@Autowired
@Qualifier("fullFeatureUploader") // 注入组合后的装饰器
private FileUploader fileUploader;
@PostMapping("/upload")
public String uploadFile(@RequestParam String filePath) {
fileUploader.upload(filePath);
return "文件处理完成";
}
}
传统方式实现
@Service
public class TraditionalFileUploader {
public void upload(String filePath,
boolean needEncrypt,
boolean needCompress,
boolean enableLogging) {
String processedFile = filePath;
if (enableLogging) {
System.out.println("【开始上传】" + LocalDateTime.now());
}
if (needEncrypt) {
System.out.println(">>> 加密文件: " + processedFile);
processedFile += ".enc";
}
if (needCompress) {
System.out.println(">>> 压缩文件: " + processedFile);
processedFile += ".zip";
}
System.out.println("[核心逻辑] 上传文件到云存储: " + processedFile);
if (enableLogging) {
System.out.println("【上传完成】" + LocalDateTime.now());
}
}
}
两种方式对比分析
1. 执行效果对比
请求示例:
POST /upload?filePath=report.pdf
装饰器模式输出:
【开始上传】2023-08-20T14:30:00.123
>>> 加密文件: report.pdf
>>> 压缩文件: report.pdf.enc
[核心逻辑] 上传文件到云存储: report.pdf.enc.zip
【上传完成】2023-08-20T14:30:02.456
传统方式输出(参数全true):
(输出结果相同,但实现方式完全不同)
2. 核心差异点
3. 装饰器模式核心优势
符合开闭原则
新增文件水印功能只需创建WatermarkDecorator
,无需触碰已有代码:@Component public class WatermarkDecorator extends FileUploadDecorator { // 实现水印功能 }
动态组合能力
根据不同场景配置不同处理流程:// 敏感文件处理流:加密 → 水印 → 上传 new WatermarkDecorator( new EncryptUploadDecorator(base) ) // 大文件处理流:压缩 → 分片 → 上传 new ChunkDecorator( new CompressUploadDecorator(base) )
功能复用便捷
同一装饰器可被多个流程复用:// 日志装饰器可应用于上传、下载等不同场景 public class LoggingDownloadDecorator extends DownloadDecorator { // 复用相同的日志逻辑 }
与AOP无缝整合
结合Spring AOP实现更强大的切面控制:@Around("execution(* com.example.upload.*.*(..))") public Object logExecutionTime(ProceedingJoinPoint joinPoint) { // 在装饰器基础上增加统一监控 }
适用场景推荐
金融交易流水线:交易验证 → 风控检查 → 记账 → 通知
多媒体处理:视频转码 → 添加字幕 → 画质增强
物联网数据处理:数据清洗 → 异常检测 → 聚合分析
API网关:鉴权 → 限流 → 缓存 → 响应格式化
电商订单流程:价格计算 → 库存锁定 → 支付 → 物流创建
装饰器模式的核心价值
通过动态包装替代静态继承,装饰器模式在以下场景展现独特优势:
业务需求频繁变更:快速响应新增功能需求
功能排列组合爆炸:避免创建大量子类
核心逻辑需要保护:不改动基础代码的前提下增强功能
系统可观测性建设:灵活添加监控、日志等非业务功能
当系统需要像"乐高积木"一样灵活组装功能模块时,装饰器模式是最优雅的解决方案之一。