当前位置: 首页 > article >正文

23种设计模式之《代理模式(Proxy)》在c#中的应用及理解

程序设计中的主要设计模式通常分为三大类,共23种:

1. 创建型模式(Creational Patterns)

  • 单例模式(Singleton):确保一个类只有一个实例,并提供全局访问点。

  • 工厂方法模式(Factory Method):定义创建对象的接口,由子类决定实例化哪个类。

  • 抽象工厂模式(Abstract Factory):提供一个创建一系列相关或依赖对象的接口,而无需指定具体类。

  • 建造者模式(Builder):将一个复杂对象的构建与其表示分离,使同样的构建过程可以创建不同的表示。

  • 原型模式(Prototype):通过复制现有对象来创建新对象。

2. 结构型模式(Structural Patterns)

  • 适配器模式(Adapter):将一个类的接口转换成客户希望的另一个接口。

  • 桥接模式(Bridge):将抽象部分与实现部分分离,使它们可以独立变化。

  • 组合模式(Composite):将对象组合成树形结构以表示“部分-整体”的层次结构。

  • 装饰器模式(Decorator):动态地给对象添加职责,相比生成子类更为灵活。

  • 外观模式(Facade):为子系统中的一组接口提供一个统一的接口。

  • 享元模式(Flyweight):通过共享技术有效地支持大量细粒度对象。

  • 代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问。

3. 行为型模式(Behavioral Patterns)

  • 责任链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者与接收者耦合。

  • 命令模式(Command):将请求封装为对象,使你可以用不同的请求对客户进行参数化。

  • 解释器模式(Interpreter):给定一个语言,定义其文法的一种表示,并定义一个解释器。

  • 迭代器模式(Iterator):提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部表示。

  • 中介者模式(Mediator):定义一个中介对象来封装一系列对象之间的交互。

  • 备忘录模式(Memento):在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。

  • 观察者模式(Observer):定义对象间的一对多依赖关系,当一个对象改变状态时,所有依赖者都会收到通知并自动更新。

  • 状态模式(State):允许对象在其内部状态改变时改变其行为。

  • 策略模式(Strategy):定义一系列算法,将它们封装起来,并使它们可以互相替换。

  • 模板方法模式(Template Method):定义一个操作中的算法骨架,将一些步骤延迟到子类中。

  • 访问者模式(Visitor):表示一个作用于某对象结构中的各元素的操作,使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。

4.代理模式(Proxy Pattern)简介

代理模式是一种结构型设计模式,它允许你提供一个代理对象来控制对另一个对象的访问。代理对象通常会在客户端和目标对象之间充当中间人,用于延迟加载、访问控制、日志记录等。

代理模式的主要角色:
  1. Subject(抽象主题):定义真实对象和代理对象的共同接口,客户端通过该接口与真实对象交互。

  2. RealSubject(真实主题):实现抽象主题接口,是代理对象所代表的真实对象。

  3. Proxy(代理):实现抽象主题接口,并持有对真实对象的引用。代理对象可以在调用真实对象之前或之后执行一些额外的操作。

5.代理模式的适用场景:

  • 延迟加载(Lazy Loading):当创建对象的开销较大时,可以使用代理模式延迟对象的创建。

  • 访问控制:代理可以控制对真实对象的访问权限。

  • 日志记录:代理可以在调用真实对象的方法前后记录日志。

  • 远程代理:代理可以代表远程对象,隐藏网络通信的细节。

6.C# 代码示例

下面是一个简单的C#示例,展示了如何使用代理模式来实现延迟加载。

csharp

using System;

// 抽象主题接口
public interface IImage
{
    void Display();
}

// 真实主题类
public class RealImage : IImage
{
    private string _fileName;

    public RealImage(string fileName)
    {
        _fileName = fileName;
        LoadImageFromDisk();
    }

    private void LoadImageFromDisk()
    {
        Console.WriteLine("Loading image: " + _fileName);
    }

    public void Display()
    {
        Console.WriteLine("Displaying image: " + _fileName);
    }
}

// 代理类
public class ProxyImage : IImage
{
    private RealImage _realImage;
    private string _fileName;

    public ProxyImage(string fileName)
    {
        _fileName = fileName;
    }

    public void Display()
    {
        if (_realImage == null)
        {
            _realImage = new RealImage(_fileName);
        }
        _realImage.Display();
    }
}

// 客户端代码
public class Client
{
    public static void Main(string[] args)
    {
        IImage image = new ProxyImage("test_image.jpg");

        // 图像尚未加载
        Console.WriteLine("Image will be loaded and displayed now.");
        image.Display();

        // 图像已经加载,无需再次加载
        Console.WriteLine("Image will be displayed again.");
        image.Display();
    }
}

7.代码解析

  1. IImage 接口:定义了 Display 方法,RealImage 和 ProxyImage 都实现了这个接口。

  2. RealImage 类:这是真实的对象,负责加载和显示图像。在构造函数中,它会从磁盘加载图像。

  3. ProxyImage 类:这是代理类,它也实现了 IImage 接口。它持有一个 RealImage 的引用,并在 Display 方法中控制对 RealImage 的访问。当 Display 方法被调用时,代理会检查 RealImage 是否已经创建,如果没有,则创建它并调用其 Display 方法。

  4. Client 类:客户端代码通过 ProxyImage 来访问 RealImage。第一次调用 Display 时,RealImage 会被创建并加载图像。第二次调用时,由于 RealImage 已经存在,代理会直接调用它的 Display 方法,而不会再次加载图像。

8.总结

代理模式通过引入一个代理对象来控制对真实对象的访问,从而可以在不改变客户端代码的情况下,增加额外的功能(如延迟加载、访问控制等)。在实际应用中,代理模式可以用于多种场景,如远程代理、虚拟代理、保护代理等。


http://www.kler.cn/a/560596.html

相关文章:

  • ddd 文章总结分享,ddd实战代码分享, 领域驱动设计java实战源码大全,我看过的ddd java源码
  • 3D Web轻量化引擎HOOPS Communicator如何赋能航空航天制造?
  • Linux编辑器
  • hackmyvm-buster
  • C语言学习,希尔排序
  • Websock Demo(一)前端代码
  • pytest运行用例的常见方式及参数
  • ChatGPT免费背后的技术暗战 国产数字孪生如何打造“虚实共生”新生态?
  • 【C】初阶数据结构7 -- 树与顺序结构的二叉树(堆)
  • 链表(LinkedList)面试题
  • 蓝桥杯客观题
  • 网络安全-新型路径攻击流程及防御措施
  • 蓝桥杯学习笔记03-滑动窗口不定长(最长/最大)
  • 性能测试项目实战
  • VMware安装CentOS 10
  • 传统 HTML 表单如何支持PUT DELETE 方法提交请求
  • Java 代理模式 (Proxy)详解
  • 最小化重投影误差求解PnP
  • 【ICE】飞冰项目中根据不同域名设置不同的网站logo
  • Python Django系列—入门实例(二)