设计模式 12 代理模式

设计模式 12

  • 创建型模式(5):工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式
  • 结构型模式(7):适配器模式、桥接模式、组合模式、装饰者模式、外观模式、享元模式、代理模式
  • 行为型模式(11):责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式、访问者模式

文章目录

  • [设计模式 12](#设计模式 12)
    • [代理模式(Proxy Pattern)](#代理模式(Proxy Pattern))
      • [1 定义](#1 定义)
      • [2 结构](#2 结构)
      • [3 示例代码](#3 示例代码)
      • [4 特点](#4 特点)
      • [5 适用场景](#5 适用场景)
      • [6 与其他模式的关系](#6 与其他模式的关系)

代理模式(Proxy Pattern)

1 定义

代理模式通过创建一个代理对象来控制对另一个对象的访问。代理对象具有与原对象相同的接口,客户端可以通过代理对象访问实际的服务对象。代理对象可以在不影响客户端的情况下,对请求进行预处理或后处理。

2 结构

代理模式的结构包含以下角色:

  • Subject(抽象主题): 定义了代理类和真实类的公共接口。
  • RealSubject(真实主题): 实现了抽象主题的接口,是代理所代表的真实对象。
  • Proxy(代理): 实现了抽象主题接口,并持有一个真实主题对象的引用。代理对象可以在调用真实对象的操作前后执行一些操作。

UML 类图

scss 复制代码
+-----------------+
|   Subject       | <--------- 抽象主题
+-----------------+                 |
| + Request()     |                 |
+-----------------+                 |
        ^                           |
        |                           |
+-----------------+         +-----------------+
|   Proxy         |         |  RealSubject    |
+-----------------+         +-----------------+
| - realSubject:  | ------- | + Request()     |
|   RealSubject   |         +-----------------+
| + Request()     |
+-----------------+

3 示例代码

假设我们有一个需要访问的图像文件对象。图像文件可能很大,所以我们希望在图像真正需要显示时才加载它。在这种情况下,我们可以使用代理模式。

抽象主题接口

csharp 复制代码
// 抽象主题
public interface IImage
{
    void Display();
}

真实主题类

csharp 复制代码
// 真实主题类:真实的图像文件
public class RealImage : IImage
{
    private readonly string _filename;

    public RealImage(string filename)
    {
        _filename = filename;
        LoadImageFromDisk();  // 模拟加载图像文件
    }

    private void LoadImageFromDisk()
    {
        Console.WriteLine($"Loading image from disk: {_filename}");
    }

    public void Display()
    {
        Console.WriteLine($"Displaying image: {_filename}");
    }
}

代理类

csharp 复制代码
// 代理类:代理图像
public class ProxyImage : IImage
{
    private RealImage _realImage;
    private readonly string _filename;

    public ProxyImage(string filename)
    {
        _filename = filename;
    }

    public void Display()
    {
        if (_realImage == null)
        {
            _realImage = new RealImage(_filename);  // 延迟加载
        }
        _realImage.Display();
    }
}

客户端代码

csharp 复制代码
class Program
{
    static void Main(string[] args)
    {
        IImage image = new ProxyImage("test_image.jpg");

        // 图像第一次显示时,代理对象会加载真实图像
        image.Display();

        // 图像再次显示时,不需要再次加载
        image.Display();
    }
}

在这个例子中:

  • 抽象主题 IImage : 定义了 Display() 方法,所有图像对象都必须实现这个方法。
  • 真实主题类 RealImage : 实现了 IImage 接口,并在构造函数中模拟加载图像文件。Display() 方法显示图像。
  • 代理类 ProxyImage : 同样实现了 IImage 接口,持有一个 RealImage 对象的引用。只有在需要时,才会加载真实的图像文件,执行延迟加载。

运行结果

运行上述代码,你会看到以下输出:

plaintext 复制代码
Loading image from disk: test_image.jpg
Displaying image: test_image.jpg
Displaying image: test_image.jpg

在这个例子中,图像在第一次调用 Display() 时才会加载,之后的调用直接显示图像,无需再次加载。这就是代理模式的延迟加载(Lazy Loading)应用。

4 特点

  • 优点:

    • 控制对象访问: 可以在不影响客户端的情况下控制对目标对象的访问。

    • 延迟加载: 通过代理可以实现对象的延迟初始化,节省资源。

    • 权限控制: 可以通过代理实现对敏感对象的访问控制。

  • 缺点:

    • 增加复杂性: 增加了类的数量和系统的复杂性。

    • 可能引入性能开销: 代理模式可能会引入额外的处理逻辑,导致性能开销。

5 适用场景

  • 需要延迟加载的场景: 当对象的创建成本较高且不经常使用时。
  • 远程对象访问: 通过网络访问远程对象时,可以使用代理来隐藏复杂性。
  • 控制访问权限: 需要对对象的访问进行权限控制时。
  • 智能引用代理: 在访问对象时附加一些额外操作,如引用计数、日志记录等。

6 与其他模式的关系

  • 装饰器模式: 代理和装饰器都通过代理控制对象,但装饰器用于添加行为,而代理用于控制访问。
  • 适配器模式: 适配器模式改变接口以适配另一系统,而代理模式不改变接口,只是控制访问。

代理模式在设计复杂系统时提供了非常灵活的对象管理方式,通过合理使用代理,可以有效地提升系统的性能和安全性。

相关推荐
〆、风神2 小时前
Spring Boot实战:基于策略模式+代理模式手写幂等性注解组件
spring boot·代理模式·策略模式
程序员JerrySUN4 小时前
设计模式每日硬核训练 Day 14:组合模式(Composite Pattern)完整讲解与实战应用
设计模式·组合模式
碎梦归途4 小时前
23种设计模式-创建型模式之工厂方法模式(Java版本)
java·设计模式·工厂方法模式
XU磊2604 小时前
Java 工厂设计模式详解:用统一入口打造灵活可扩展的登录系统----掌握 Spring 源码的基础第一步
java·设计模式
匹马夕阳5 小时前
java开发中的设计模式之工厂模式
java·设计模式
Pasregret5 小时前
设计模式入门:从 GoF 分类到 SOLID 原则实战
java·设计模式
Light607 小时前
Python依赖注入完全指南:高效解耦、技术深析与实践落地
python·设计模式·单元测试·fastapi·依赖注入·解耦
都叫我大帅哥8 小时前
代码界的「俄罗斯套娃」:组合模式的嵌套艺术
java·后端·设计模式
忘梓.10 小时前
解锁动态规划的奥秘:从零到精通的创新思维解析(9)
算法·动态规划·代理模式
渊渟岳11 小时前
为了掌握设计模式,开发了一款Markdown 文本编辑器软件(已开源)
java·设计模式