Bootstrap

装饰器模式的适用场景示例

1. 动态扩展和撤销类的功能

假设我们有一个 ApiRequest 类,用于发送 HTTP 请求。在某些场景下,我们希望对传输的数据进行加密以提高安全性,但在其他场景下不需要加密。通过装饰器模式,可以轻松地在需要时动态扩展这个功能,并在不需要时撤销它。

  • 场景实现
    • ApiRequest 类负责发送普通的 HTTP 请求。
    • EncryptionDecorator 装饰器类可以在需要时对数据进行加密。
    • 当请求的安全性要求高时,可以使用 EncryptionDecorator 对请求进行加密;否则直接使用 ApiRequest
// 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 + ")";
    }
}
  • 使用示例
public class Main {
    public static void main(String[] args) {
        ApiRequest basicRequest = new BasicApiRequest();

        // 如果需要加密功能
        ApiRequest secureRequest = new EncryptionDecorator(basicRequest);
        secureRequest.sendRequest("敏感信息"); // 输出: 发送请求: 加密数据(敏感信息)

        // 如果不需要加密功能
        basicRequest.sendRequest("普通信息"); // 输出: 发送请求: 普通信息
    }
}
  • 效果:通过装饰器模式,可以在运行时动态地添加或撤销加密功能,满足了场景中对安全性要求的不同需求。
2. 无法通过继承扩展类的场景

有时我们无法继承一个类,例如该类被声明为 final。装饰器模式在这种情况下提供了一个解决方案,通过组合的方式对类进行功能扩展,而不是通过继承。

  • 场景实现
    假设我们有一个 finalReportGenerator,负责生成报表。现在,我们想要在生成的报表内容前后添加公司信息和时间戳等装饰信息。
// 最终报表生成类
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();
    }
}
  • 使用示例
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 的,装饰器模式依然允许我们灵活地对报表内容进行增强,使得装饰内容可根据需求动态组合和独立变化,避免了对类进行继承扩展的局限。
;