【设计模式】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,以执行业务逻辑,以及代理对象附加的日志操作。

适用范围

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

相关推荐
范中勤1 小时前
技术文档:模型工厂 `llm_provider` / `llm_use` 分层设计
设计模式·langchain·架构设计·模型工厂·llm_provider
浅尝辄止;4 小时前
设计模式在HIS/LIS医疗系统中的完整实践指南(C#版)
开发语言·设计模式·c#
范中勤4 小时前
适配器模式(Adapter Pattern):原理、场景与 LLM 多厂商工程落地
设计模式·架构·langchain·适配器模式·多厂商
408高手15 小时前
23种设计模式
设计模式
沫璃染墨16 小时前
《Linux工程实践篇(二):线程池实战——从线程安全单例到完整源码实现》
linux·开发语言·c++·单例模式·设计模式·系统架构
sarasuki1 天前
MCP 为什么是一个协议而不是一个框架呢?
设计模式·agent·mcp
YumiProxy1 天前
代理IP自动切换避坑指南:会话保持、请求头与错误处理实战
网络·网络协议·tcp/ip·代理模式·ip
geovindu1 天前
rust: Borg Pattern(续)
开发语言·后端·设计模式·rust·博格模式
染指11102 天前
140.Agent-多Agent框架-Agent执行Skills流程
数据库·人工智能·设计模式·langchain·agents
sarasuki2 天前
Agent 是怎么做错误处理的呢?
人工智能·设计模式·agent