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

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。装饰器模式在这种情况下提供了一个解决方案,通过组合的方式对类进行功能扩展,而不是通过继承。

  • 场景实现
    假设我们有一个 finalReportGenerator,负责生成报表。现在,我们想要在生成的报表内容前后添加公司信息和时间戳等装饰信息。
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 的,装饰器模式依然允许我们灵活地对报表内容进行增强,使得装饰内容可根据需求动态组合和独立变化,避免了对类进行继承扩展的局限。
相关推荐
repinkply1 天前
装饰模式(Decorator)模式:装饰模式/包装模式,结构模式
设计模式·c++设计模式·装饰器模式·装饰模式·包装模式
霁月风1 天前
设计模式——装饰器模式
c++·设计模式·装饰器模式
捕鲸叉4 天前
C++设计模式之适配器模式与桥接模式,装饰器模式及代理模式相似点与不同点
设计模式·桥接模式·适配器模式·装饰器模式
Miqiuha8 天前
装饰器设计模式学习
java·学习·装饰器模式
南城花随雪。10 天前
Spring框架之装饰者模式 (Decorator Pattern)
java·开发语言·装饰器模式
编程、小哥哥10 天前
设计模式之装饰器模式(SSO单点登录功能扩展,增加拦截用户访问方法范围场景)
java·设计模式·装饰器模式
吾与谁归in10 天前
【C#设计模式(10)——装饰器模式(Decorator Pattern)】
设计模式·c#·装饰器模式
编码熊(Coding-Bear)20 天前
设计模式之结构型模式---装饰器模式
android·java·设计模式·装饰器模式
G皮T21 天前
【设计模式】结构型模式(一):适配器模式、装饰器模式
java·设计模式·适配器模式·装饰器模式·decorator·adapter·结构型模式
无敌岩雀22 天前
C++设计模式结构型模式———装饰模式
c++·设计模式·装饰器模式