1. 动态扩展和撤销类的功能
假设我们有一个 ApiRequest
类,用于发送 HTTP 请求。在某些场景下,我们希望对传输的数据进行加密以提高安全性,但在其他场景下不需要加密。通过装饰器模式,可以轻松地在需要时动态扩展这个功能,并在不需要时撤销它。
- 场景实现 :
ApiRequest
类负责发送普通的 HTTP 请求。EncryptionDecorator
装饰器类可以在需要时对数据进行加密。- 当请求的安全性要求高时,可以使用
EncryptionDecorator
对请求进行加密;否则直接使用ApiRequest
。
java
// API请求接口
public interface ApiRequest {
void sendRequest(String data);
}
// 基础API请求类
public class BasicApiRequest implements ApiRequest {
@Override
public void sendRequest(String data) {
System.out.println("发送请求: " + data);
}
}
// 加密装饰器
public class EncryptionDecorator implements ApiRequest {
private ApiRequest wrappedRequest;
public EncryptionDecorator(ApiRequest wrappedRequest) {
this.wrappedRequest = wrappedRequest;
}
@Override
public void sendRequest(String data) {
String encryptedData = encrypt(data);
wrappedRequest.sendRequest(encryptedData);
}
private String encrypt(String data) {
return "加密数据(" + data + ")";
}
}
- 使用示例:
java
public class Main {
public static void main(String[] args) {
ApiRequest basicRequest = new BasicApiRequest();
// 如果需要加密功能
ApiRequest secureRequest = new EncryptionDecorator(basicRequest);
secureRequest.sendRequest("敏感信息"); // 输出: 发送请求: 加密数据(敏感信息)
// 如果不需要加密功能
basicRequest.sendRequest("普通信息"); // 输出: 发送请求: 普通信息
}
}
- 效果:通过装饰器模式,可以在运行时动态地添加或撤销加密功能,满足了场景中对安全性要求的不同需求。
2. 无法通过继承扩展类的场景
有时我们无法继承一个类,例如该类被声明为 final
。装饰器模式在这种情况下提供了一个解决方案,通过组合的方式对类进行功能扩展,而不是通过继承。
- 场景实现 :
假设我们有一个final
类ReportGenerator
,负责生成报表。现在,我们想要在生成的报表内容前后添加公司信息和时间戳等装饰信息。
java
// 最终报表生成类
public final class ReportGenerator {
public String generate() {
return "报表内容";
}
}
// 报表装饰器接口
public interface ReportDecorator {
String generateReport();
}
// 公司信息装饰器
public class CompanyInfoDecorator implements ReportDecorator {
private ReportGenerator reportGenerator;
public CompanyInfoDecorator(ReportGenerator reportGenerator) {
this.reportGenerator = reportGenerator;
}
@Override
public String generateReport() {
return "公司信息: ABC公司\n" + reportGenerator.generate();
}
}
// 时间戳装饰器
public class TimestampDecorator implements ReportDecorator {
private ReportGenerator reportGenerator;
public TimestampDecorator(ReportGenerator reportGenerator) {
this.reportGenerator = reportGenerator;
}
@Override
public String generateReport() {
return reportGenerator.generate() + "\n生成时间: " + System.currentTimeMillis();
}
}
- 使用示例:
java
public class Main {
public static void main(String[] args) {
ReportGenerator report = new ReportGenerator();
// 添加公司信息
ReportDecorator companyReport = new CompanyInfoDecorator(report);
System.out.println(companyReport.generateReport());
// 添加时间戳
ReportDecorator timestampedReport = new TimestampDecorator(report);
System.out.println(timestampedReport.generateReport());
}
}
- 效果 :即使
ReportGenerator
类是final
的,装饰器模式依然允许我们灵活地对报表内容进行增强,使得装饰内容可根据需求动态组合和独立变化,避免了对类进行继承扩展的局限。