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

适用范围

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

相关推荐
怕浪猫17 小时前
一行命令复刻爆款视频,我把 Hypit 从安装跑到了出片
人工智能·设计模式·程序员
Zane199419 小时前
函数式编程里的函数,其实不是你天天写的那个函数——三大编程范式的边界在哪
设计模式
Zane19942 天前
策略模式现在该不该上?一次讲清楚过度设计和设计不足怎么找平衡
设计模式
她说..2 天前
常见设计模式-模板方法模式
java·spring·设计模式·springboot
xiaofeiyang1502 天前
第六章 · 桥接 — 三支毛笔,画出九种颜色
设计模式
IPdodo_3 天前
住宅 IP 与数据中心 IP 到底差在哪:用 RDAP、BGP 和多源证据做工程判定
网络·网络安全·代理模式·ip
Shadow(⊙o⊙)3 天前
OTOL设计模式 One Thread One Loop
服务器·网络·设计模式
sarasuki4 天前
如何让LLM 能在半夜偷偷打开网易云呢?
人工智能·设计模式·agent
小王师傅664 天前
【设计模式】装饰模式(四):框架源码实战——从 Java I/O 到 Spring 到 MyBatis
java·设计模式
执明wa4 天前
Android RecyclerView 多类型, 多种 Item
android·xml·开发语言·设计模式·android studio