【设计模式】GoF设计模式之代理模式(Proxy Pattern)

设计模式之代理模式 Proxy Pattern

V1.0

核心思想

代理模式是一种结构型设计模式,其核心思想是使用代理类(Proxy)对业务类(真实主题类RealSubject)进行封装,代理类和业务类都实现相同的接口。代理类对象持有业务类对象,在调用代理类对象的接口时,代理类对象可以在转发调用行为到真实主题对象的之前或之后进行一些诸如日志记录、权限控制等操作。

真实主题的实例通常可以单独使用,以实现业务功能,而无需使用代理类进行封装。

角色

  • Subject(抽象主题接口)
    主题接口定义了真实主题和代理类的共同接口,通过调用这些接口可以实现业务功能。
    具体而言,直接调用真实主题对象的接口,可以直接实现业务功能,而调用代理对象的接口,代理对象可以进行一些处理,并将调用操作转发到真实主题对象。
  • RealSubject(真实主题类)
    真实主题类是具体的业务类,实现了抽象主题接口Subject,通常可以单独使用,以完成业务功能。
  • Proxy(代理类)
    代理类实现了抽象主题接口Subject,代理对象会持有一个真实主题对象,会在将调用请求转发到真实主题类对象的之前或之后进行一些处理,以完成指定的功能。

代码示例

csharp 复制代码
/// <summary>
/// 抽象主题接口
/// </summary>
public interface ISubject
{
    public void CuttingDiamond(double weight);
}

/// <summary>
/// 真实主题, 即业务类, 钻石切割机
/// </summary>
public class RealSubjectDiamondCutter : ISubject
{

    public void CuttingDiamond(double weight)
    {
        Console.WriteLine($"Cutting a diamond of {weight:F2} ct");
    }
}

/// <summary>
/// 代理类, 持有真实主题对象(业务对象), 进行操作转发, 并在转发之前或之后执行需要的动作
/// </summary>
public class Proxy : ISubject
{
    //代理类持有真实主题对象
    private ISubject cutter;

    //创建代理类时, 需要传入真实主题对象
    public Proxy(ISubject cutter)
    {
        this.cutter = cutter;
    }

    public void CuttingDiamond(double weight)
    {
        cutter.CuttingDiamond(weight);

        //真实主题的业务操作完成后, 模拟操作日志的记录
        Console.WriteLine($"The task has been completed smoothly on {DateTime.Now.ToString("HH:mm:ss")}");
    }
}

public class Client
{
    public static void Main(string[] arg)
    {
        //建立真实主题对象
        RealSubjectDiamondCutter cutter = new();

        //建立代理对象
        Proxy proxy = new(cutter);

        //通过代理对象进行操作
        proxy.CuttingDiamond(1.5);

        //模拟延时, 等待下1个任务
        Thread.Sleep(2000);

        //通过代理对象进行操作
        proxy.CuttingDiamond(2);
    }
}

程序运行结果

复制代码
Cutting a diamond of 1.50 ct
The task has been completed smoothly on 23:06:08
Cutting a diamond of 2.00 ct
The task has been completed smoothly on 23:06:10

代码讲解

  • ISubject(抽象代理接口)
    ISubject是抽象代理接口,定义了切割钻石的接口,真实主题RealSubjectDiamondCutter和代理类Proxy对应该实现该接口。
  • RealSubjectDiamondCutter(真实主题类)
    RealSubjectDiamondCutter是真实主题类,实现了ISubject定义的动作接口CuttingDiamond,完成了具体的业务。
  • Proxy(代理类)
    Proxy是代理类,持有一个真实主题对象cutter,实现了ISubject接口定义的动作接口CuttingDiamond,具体为将动作请求转发到真实主题对象的相应的CuttingDiamond接口,执行业务逻辑,之后进行了日志操作。
  • Client(客户端类)
    Client是客户端类, 其中创建了真实主题对象cutter,并使用cutter创建了代理对象proxy。之后调用代理对象的方法CuttingDiamond,以执行业务逻辑,以及代理对象附加的日志操作。

适用范围

代理模式可以对业务对象进行封装,对访问进行控制,同时可以增加额外的功能,具体包括日志记录、权限控制、延迟加载等。

相关推荐
AustinXu1 小时前
从 Claude Code 到 Claude Tag,Harness Engineering 走到了组织这一层
设计模式·团队管理
剧中有戏1 小时前
单例模式从入门到精通:一个数据库连接池的完整剖析
设计模式
胡萝卜术2 小时前
编译期与运行期的双重防线:从 TypeScript 类型之争到 LLM 输出的自动化择优
前端·设计模式·面试
货拉拉技术2 小时前
重塑 Agent 度量衡:基于 LLM-as-a-Judge 的离线评估体系与实践
算法·设计模式
KhalilRuan2 小时前
设计模式小记
设计模式
卡牌RWA研究院3 小时前
Relique:一张精品卡牌如何从收藏品变成可交易的链上资产?
设计模式·金融·区块链·创业创新
只吃不吃香菜3 小时前
Windows 下基于 YAML 规则的指定域名分流:以哔哩哔哩为例
网络·网络协议·计算机网络·网络安全·代理模式
剧中有戏1 天前
抽象工厂模式从入门到精通:一个多云存储案例的完整剖析(修订版)
设计模式
MC皮蛋侠客1 天前
Redis 系列(八):缓存设计模式与一致性——从 Cache Aside 到防雪崩
redis·缓存·设计模式
莫得感情 o1 天前
设计模式 18 · 状态模式
设计模式·状态模式