首页 > 编程语言 >C# 设计模式之代理模式

C# 设计模式之代理模式

时间:2024-08-08 19:24:52浏览次数:12  
标签:C# Image 代理 fileName 对象 设计模式 public 客户端

总目录


前言

其实代理模式,在生活中无处不在;就比如租房,一般都是通过中介或者第三方的App去租房子(此处默认他们都是诚信友好的哈),那么为什么我们不自己找房子呢?租过房子应该都知道,自己找房子太麻烦了,既要找原房东,又要搞合同,出了问题扯皮也扯不清等等一些问题,主要是费时费力。那么中介 和 第三方app 就相当于代理了,直接找他们省时省力,很多事情不用管,都由代理去搞定,我们只需看到满意的房子为止。那么我们接下来看看代码中设计模式是如何实现的吧。


1 基础介绍

  1. 定义:为其他对象提供一种代理以控制对这个对象的访问。

  2. 代理模式的本质就是在客户端和目标对象之间添加一个中介,中介在原对象基础上包了一层封装,封装的时候可以有选择性,有目的性的实现原对象中功能,避免了客户端和目标对象的直接接触,而是通过中介访问。

  3. 代理模式其实没有什么固定的结构,如果是开发初期有计划的开发代理类,可以分为3个角色:

    • 抽象角色(Subject):它声明了真实对象和代理对象的共同接口,真实角色和代理角色继承自抽象角色。
    • 真实角色(RealSubject):继承自抽象角色,实现其真实的业务操作。
    • 代理角色(Proxy):继承自抽象角色,在角色内部创建真实角色的实例,对其内函数进行加工封装操作,以供客户端使用。
  4. 代理模式按照使用目的可以分为以下几种:

    • 远程(Remote)代理:为一个位于不同的地址空间的对象提供一个局域代表对象。这个不同的地址空间可以是本电脑中,也可以在另一台电脑中。最典型的例子就是——客户端调用Web服务或WCF服务。
    • 虚拟(Virtual)代理:根据需要创建一个资源消耗较大的对象,使得对象只在需要时才会被真正创建。
    • Copy-on-Write代理:虚拟代理的一种,把复制(或者叫克隆)拖延到只有在客户端需要时,才真正采取行动。
    • 保护(Protect or Access)代理:控制一个对象的访问,可以给不同的用户提供不同级别的使用权限。
    • 防火墙(Firewall)代理:保护目标不让恶意用户接近。
    • 智能引用(Smart Reference)代理:当一个对象被引用时,提供一些额外的操作,比如将对此对象调用的次数记录下来等。
    • Cache代理:为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以这些结果。

那么问题来了,为什么不直接使用原对象,反而多此一举的创建这个第三者出来呢。下面就通过一些例子来具体说明。


举例说明:

场景一:使用第三方登录时,比如QQ、微信登录,我们不可能直接引用第三方那边的任何源代码的东西,但可以通过封装第三方暴露出来的api才进行开发。在这个场景里,第三方的api就是原对象,我们做封装的类就是代理类。想要实现登录功能,就可以通过代理类来进行。这种网络通信中封装操作就是远程代理


场景二:在日常开发中,同一个产品,可能对普通用户只开放一小部分功能,对VIP客户开放大部分功能,对管理者开放所有功能。针对不同权限有针对性的开放不同功能,那我们就可以在原对象基础上做封装来实现代理,封闭原对象所有功能。这个封装的代理类就可以控制这个对象的访问,可以给不同的用户提供不同级别的使用权限。这种有选择的开放就是保护代理


场景三:大家在下载文件或者加载比较复杂的网站时,总会出现一个进度条或者加载loading,这个进度条或loading就使用的代理模式。这种使用消耗小,速度快的效果来替代表示的就是虚拟代理


场景四:缓存Redis大家应该都使用过,它的作用就是把多终端频繁需要访问的数据从数据库临时存储在内存中共所有终端使用。这种就是缓冲代理

2 使用场景

代理模式的类型较多,它们应用于不同的场合:
(1)、 当客户端对象需要访问远程主机中的对象时可以使用远程代理。
(2)、当需要用一个消耗资源较少的对象来代表一个消耗资源较多的对象,从而降低系统开销、缩短运行时间时可以使用虚拟代理,例如一个对象需要很长时间才能完成加载时。
(3)、当需要为某一个被频繁访问的操作结果提供一个临时存储空间,以供多个客户端共享访问这些结果时可以使用缓冲代理。通过使用缓冲代理,系统无须在客户端每一次访问时都重新执行操作,只需直接从临时缓冲区获取操作结果即可。
(4)、 当需要控制对一个对象的访问,为不同用户提供不同级别的访问权限时可以使用保护代理。
(5)、当需要为一个对象的访问(引用)提供一些额外的操作时可以使用智能引用代理。

3 实现方式

	 public interface Image
    {
        //加载图片
        void Load();
        //显示图片
        void Dispaly();
    }

    public class RealImage : Image
    {

        public void Dispaly()
        {
            Console.WriteLine("图片显示中");
        }

        public void Load()
        {
            Console.WriteLine("图片加载中");
        }
    }

    // 定义一个代理类,这是代理模式的核心
    public class ProxyImage : Image
    {
        private Image _Image;
        private string _fileName;
        public ProxyImage(string fileName)
        {

            _fileName = fileName;

        }
        public void Dispaly()
        {
            Console.WriteLine($"{_fileName}图片:开始展示");
            _Image.Dispaly();
            Console.WriteLine($"{_fileName}图片:已经显示");
        }

        public void Load()
        {
            Console.WriteLine($"{_fileName}图片:开始加载");
            _Image.Load();
            Console.WriteLine($"{_fileName}图片:加载完成");

        }
    }

客户端调用:

        static void Main(string[] args)
        {
            Image image = new ProxyImage("机器猫");
            image.Load();
            image.Dispaly();

            Console.ReadKey();
        }

从上面案例中,我们可以看到,通过使用代理类,我们可以避免核心的业务逻辑类有太多的冗余逻辑,让其只关注于业务的实现;同时,代理类也可以辅助核心业务实现类,完成一些日记记录等额外操作,让系统功能更趋完善;代理模式也实现了具体实现类和客户之间的解耦,所有的操作只需要通过统一的代理类来进行就可以了。

4 优缺点分析

  • 优点

    • 代理模式能够将真正被调用的对象隔离,在一定程度上降低了系统的耦合度;
    • 代理对象在客户端和目标对象之间起到一个中介的作用,这样可以起到对目标对象的保护。
    • 代理对象可以在对目标对象发出请求之前进行一个额外的操作,例如权限检查等。
  • 缺点

    • 可能会降低系统的性能和增加内存消耗,因为需要通过代理对象来访问真实对象。
    • 实现代理类也需要额外的工作,从而增加了系统的实现复杂度。

结语

希望以上内容可以帮助到大家,如文中有不对之处,还请批评指正。

世事一场大梦,人生几度秋凉。——苏轼《西江月》


参考资料:
c#中代理模式详解
C#设计模式(13)——代理模式(Proxy Pattern)
C#设计模式之十二代理模式(Proxy Pattern)【结构型】
C#设计模式12——代理模式的写法

标签:C#,Image,代理,fileName,对象,设计模式,public,客户端
From: https://blog.csdn.net/qq_39847278/article/details/140957657

相关文章

  • 2024睿抗机器人开发者大赛(RAICOM) CAIP编程技能赛 国一
    最后91分,国一。前几题都AK了,最后一题先是输出0,得了个1分。花了一个小时都没解决这题,难受ing,其实到最后差不多要改对了(降落那一部分没时间改),但是没时间了,hhhh。拿到国一,简直圆梦啦!!!本科拿的国三,差0.02秒就是国二,从此内心蒙上阴影。哭死ing研一终于拿了个编程比赛的国一,也算......
  • MIMIC IV 3.0数据库安装方法
            MIMICIV3.0在上月已经发布了,那么如何安装这个最新的MIMIC数据库呢?1.MIMICIV3.0数据库变化情况        2024年7月19日,知名医疗数据库MIMIC-IV发布了最新的3.0版本,此次更新为数据库带来了诸多重要改进和新增数据。此次更新最显著的变化是新增了20......
  • [Typescript] The declare module Syntax in TypeScript
    Herewe'reimportingafunction myModuleFunc from my-module:import{myModuleFunc}from"my-module";//redsquigglylineunder"my-module" Let'sstartbycreatinganewdeclarationfilecalled my-module.d.ts insideofth......
  • c语言中输出字符指针相关问题
    原文链接:https://blog.csdn.net/littesss/article/details/71037908c语言中输出字符指针相关问题一、例如定义一个char*p="hello";的字符指针。首先搞清楚在c语言中没有字符串的类型,所以对字符串操作,有两种形式:可以用字符指针(为什么不叫字符串指针,我个人觉得,字符指针针对......
  • 基于SiliconCloud快速体验GraphRag.Net
    SiliconCloud介绍SiliconCloud基于优秀的开源基础模型,提供高性价比的GenAI服务。不同于多数大模型云服务平台只提供自家大模型API,SiliconCloud上架了包括Qwen、DeepSeek、GLM、Yi、Mistral、LLaMA3、SDXL、InstantID在内的多种开源大语言模型及图片生成模型,用户可自由切......
  • [Typescript] tsconfig libs and target
    Intsconfigfile,youhave targetand libsconfiguration.Youalwaysneedtodefinea target,recommendedas es2022Specifyingthe lib optionalsoletsusdrilldownintothespecificfeaturesandlibrarieswewanttoincludeinourproject,whichwewill......
  • 暑假集训CSP提高模拟16
    1.九次九日九重色一开始做的时候被题面给迷惑住了,没想到可以跳着匹配(样例太水)。那我们来考虑如何做,首先思路肯定是把能匹配的暴力求出来,根据不知道怎么搞的调和计数,这样的复杂度还不是很高,是\(O(NlogN)\),可以搞。观察一下预处理出来的序列,是不是很熟悉。没错剩下的就是求最......
  • C数组和指针,从此不再困惑。
    目录一、思考下图中的问题?二、上图中问题答案,如下图:三、分析问题答案1、分析前知识准备1.0、内存区术语1.1、为什么定义数组类型变量时要指定大小或初始化1.2、指针指向的内存一定是在堆区吗?1.3、const关键字的思考1.4、进程虚拟地址空间1.5、为什么会段错误?2、开始......
  • Spring Cloud微服务项目聚合Swagger文档
            在微服务架构中,每个服务通常都有自己独立的API文档。为了方便管理和查看所有服务的接口文档,我们需要将这些文档进行聚合。SpringCloud与Swagger的结合可以帮助我们实现这一目标。本文将介绍如何在SpringCloud微服务项目中聚合Swagger文档,以便于集中......
  • AI绘画 Stable Diffusion后期处理—无需ControlNet也能轻松高清放大图像与老旧照片修
    大家好,我是设计师阿威分享了这么多期AI绘画StableDIffusion的入门教程和一些常用的插件玩法后,不知道大家有没有发现,SD还有一个功能,似乎没怎么用到过,它就是—后期处理。今天就给大家分享一下SD中的“后期处理”的常用玩法。后期处理可以选择「单张照片」、「批量处理......