首页 > 其他分享 >ProxyPattern-代理模式

ProxyPattern-代理模式

时间:2023-08-21 19:23:21浏览次数:35  
标签:Console iSubject ProxyPattern 模式 代理 GetSomethingLong WriteLine DoSomethingLong p

在C#中,代理模式(Proxy Pattern)是一种结构型设计模式,它允许通过创建一个代理对象来控制对其他对象的访问。代理对象充当着客户端和被代理对象之间的中间层,可以在访问对象时添加额外的功能,例如权限验证、延迟加载等。

代理模式有以下几个关键角色:

Subject(主题):定义了代理对象和真实对象的共同接口,客户端通过该接口访问真实对象。

RealSubject(真实主题):是代理模式中被代理的对象。它实现了Subject接口,并定义了真实对象的业务逻辑。

Proxy(代理):实现了Subject接口,并持有一个真实主题的引用。它可以代理客户端的请求,在调用真实主题前后执行额外的逻辑。

namespace ProxyPattern_代理模式
{
    /// <summary>
    /// 业务接口
    /// </summary>
    public interface ISubject
    {
        List<string> GetSomethingLong();
        void DoSomethingLong();
    }
}
namespace ProxyPattern_代理模式
{
    /// <summary>
    /// 具体业务
    /// </summary>
    public class RealSubject: ISubject
    {
        public RealSubject()
        {
            Thread.Sleep(2000);
            Console.WriteLine("RealSubject被构造。。。");
        }

        public void DoSomethingLong()
        {
            Thread.Sleep(1000);
            Console.WriteLine("DoSomethingLong");
        }

        public List<string> GetSomethingLong()
        {
            Thread.Sleep(1000);
            Console.WriteLine("GetSomethingLong");
            return new List<string>() { "123", "456", "789" };
        }
    }
}
namespace ProxyPattern_代理模式
{
    internal class Program
    {
        static void Main(string[] args)
        {
            {
                ISubject subject = new RealSubject();
                subject.GetSomethingLong();
                subject.DoSomethingLong();
                //输出结果
                //RealSubject被构造。。。
                //GetSomethingLong
                //DoSomethingLong
            }
        }
    }
}

当我们需要新增运行日志或者额外代码逻辑时,可以使用代理模式增加此功能,符合开闭原则

namespace ProxyPattern_代理模式
{
    public class ProxySubject : ISubject
    {
        private ISubject _iSubject = new RealSubject();
        public void DoSomethingLong()
        {
            Console.WriteLine("prepare DoSomethingLong");
            _iSubject.DoSomethingLong();
        }

        public List<string> GetSomethingLong()
        {
            Console.WriteLine("prepare GetSomethingLong");
            return _iSubject.GetSomethingLong();
        }
    }
}
namespace ProxyPattern_代理模式
{
    internal class Program
    {
        static void Main(string[] args)
        {
            {
                ISubject subject = new RealSubject();
                subject.GetSomethingLong();
                subject.DoSomethingLong();
                //输出结果
                //RealSubject被构造。。。
                //GetSomethingLong
                //DoSomethingLong
            }
            {
                ISubject subject = new ProxySubject();
                subject.GetSomethingLong();
                subject.DoSomethingLong();
                //输出结果
                //RealSubject被构造。。。
                //prepare GetSomethingLong
                //GetSomethingLong
                //prepare DoSomethingLong
                //DoSomethingLong
            }
            {

            }
            Console.Read();
        }
    }
}

异常代理,在代理类中增加try-catch异常处理

namespace ProxyPattern_代理模式
{
    public class ProxySubject : ISubject
    {
        private ISubject _iSubject = new RealSubject();
        public void DoSomethingLong()
        {
            try
            {
                Console.WriteLine("prepare DoSomethingLong");
                _iSubject.DoSomethingLong();
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        public List<string> GetSomethingLong()
        {
            try
            {
                Console.WriteLine("prepare GetSomethingLong");
                List<string> result = new List<string>();
                result = _iSubject.GetSomethingLong();

                return result;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                throw;
            }
        }
    }
}

单例代理,将原本不具备单例的类使用代理模式增加单例。在实例化ISubject类时使用静态关键字static

namespace ProxyPattern_代理模式
{
    public class ProxySubject : ISubject
    {
        private static ISubject _iSubject = new RealSubject();
        public void DoSomethingLong()
        {
            try
            {
                Console.WriteLine("prepare DoSomethingLong");
                _iSubject.DoSomethingLong();
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        public List<string> GetSomethingLong()
        {
            try
            {
                Console.WriteLine("prepare GetSomethingLong");
                List<string> result = new List<string>();
                result = _iSubject.GetSomethingLong();

                return result;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                throw;
            }
        }
    }
}

缓存代理,第一次请求得到的结果找个地方存起来,下次直接用,以节约时间。封装一个第三方缓存,代理查询时,优先缓存。

namespace ProxyPattern_代理模式
{
    public class CustomCache
    {
        /// <summary>
        /// 第三方存储---保证数据不丢失--可以放进来--可以获取---缓存
        /// </summary>
        private static Dictionary<string, object> CustomCacheDictionary = new Dictionary<string, object>();

        public static void Add(string key, object oValue)
        {
            CustomCacheDictionary.Add(key, oValue);
        }

        public static T GetT<T>(string key)
        {
            return (T)CustomCacheDictionary[key];
        }

        public static bool Exists(string key)
        {
            return CustomCacheDictionary.ContainsKey(key);
        }

    }
}
namespace ProxyPattern_代理模式
{
    public class ProxySubject : ISubject
    {
        private static ISubject _iSubject = new RealSubject();
        public void DoSomethingLong()
        {
            try
            {
                Console.WriteLine("prepare DoSomethingLong");
                _iSubject.DoSomethingLong();
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        public List<string> GetSomethingLong()
        {
            try
            {
                Console.WriteLine("prepare GetSomethingLong");
                string key = $"{nameof(ProxySubject)}_{nameof(GetSomethingLong)}";
                List<string> result = new List<string>();
                //在缓存中进行查询
                if (!CustomCache.Exists(key))
                {
                    result = _iSubject.GetSomethingLong();
                    CustomCache.Add(key, result);
                }
                else
                {
                    result = CustomCache.GetT<List<string>>(key);
                }

                return result;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                throw;
            }
        }
    }
}

 延迟代理,在浏览网页时,通常优先加载客户能看的界面,看不到的可以先不加载,待客户滑动后再进行加载,以此达到节约资源和效率优化的目的。

    public class ProxySubject : ISubject
    {
        private static ISubject _iSubject = null;// new RealSubject();
        private void Init()
        {
            _iSubject = new RealSubject();//把一开始就构造对象  延迟到 调用Init才会初始化
        }
        public void DoSomethingLong()
        {
            try
            {
                Console.WriteLine("prepare DoSomethingLong");
                //查询实例是否为空
                if (_iSubject == null)
                {
                    this.Init();
                }
                _iSubject.DoSomethingLong();
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        public List<string> GetSomethingLong()
        {
            try
            {
                Console.WriteLine("prepare GetSomethingLong");
                //查询实例是否为空
                if (_iSubject == null)
                {
                    this.Init();
                }
                string key = $"{nameof(ProxySubject)}_{nameof(GetSomethingLong)}";
                List<string> result = new List<string>();
                //在缓存中进行查询
                if (!CustomCache.Exists(key))
                {
                    result = _iSubject.GetSomethingLong();
                    CustomCache.Add(key, result);
                }
                else
                {
                    result = CustomCache.GetT<List<string>>(key);
                }

                return result;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                throw;
            }
        }
    }
}

权限代理,在执行操作前需要查明操作人是否具有该操作权限时可以使用代理模式增加权限管控

namespace ProxyPattern_代理模式
{
    public class ProxySubject : ISubject
    {
        private static ISubject _iSubject = null;// new RealSubject();
        private void Init()
        {
            _iSubject = new RealSubject();//把一开始就构造对象  延迟到 调用Init才会初始化
        }
        public void DoSomethingLong()
        {
            try
            {
                //权限检查
                object user = CallContext.GetData("CurrentUser");
                if (user == null)
                {
                    throw new Exception("没有权限访问");
                }
                Console.WriteLine("prepare DoSomethingLong");
                //查询实例是否为空
                if (_iSubject == null)
                {
                    this.Init();
                }
                _iSubject.DoSomethingLong();
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        public List<string> GetSomethingLong()
        {
            try
            {
                //权限检查
                object user = CallContext.GetData("CurrentUser");
                if (user == null)
                {
                    throw new Exception("没有权限访问");
                }
                Console.WriteLine("prepare GetSomethingLong");
                //查询实例是否为空
                if (_iSubject == null)
                {
                    this.Init();
                }
                string key = $"{nameof(ProxySubject)}_{nameof(GetSomethingLong)}";
                List<string> result = new List<string>();
                //在缓存中进行查询
                if (!CustomCache.Exists(key))
                {
                    result = _iSubject.GetSomethingLong();
                    CustomCache.Add(key, result);
                }
                else
                {
                    result = CustomCache.GetT<List<string>>(key);
                }

                return result;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return null;
            }
        }
    }
}
namespace ProxyPattern_代理模式
{
    internal class Program
    {
        static void Main(string[] args)
        {
            {
                //ISubject subject = new RealSubject();
                //subject.GetSomethingLong();
                //subject.DoSomethingLong();
                ////输出结果
                ////RealSubject被构造。。。
                ////GetSomethingLong
                ////DoSomethingLong
            }
            {
                //ISubject subject = new ProxySubject();
                //subject.GetSomethingLong();
                //subject.DoSomethingLong();
                ////输出结果
                ////RealSubject被构造。。。
                ////prepare GetSomethingLong
                ////GetSomethingLong
                ////prepare DoSomethingLong
                ////DoSomethingLong
            }
            {
                ISubject subject = new ProxySubject();
                subject.GetSomethingLong();
                CallContext.SetData("CurrentUser", "小明");
                subject.GetSomethingLong();
                //输出结果
                //没有权限访问
                //prepare GetSomethingLong
                //RealSubject被构造。。。
                //GetSomethingLong
            }
            Console.Read();
        }
    }
}

代理模式在需要控制对某个对象的访问时非常有用。通过代理对象,可以添加额外的逻辑或控制访问权限,而无需修改真实对象的代码。代理模式还可以实现延迟加载,在需要时才真正创建和初始化真实对象,提升系统性能。

标签:Console,iSubject,ProxyPattern,模式,代理,GetSomethingLong,WriteLine,DoSomethingLong,p
From: https://www.cnblogs.com/ZHIZRL/p/17646825.html

相关文章

  • 深入理解MVVM架构模式
    MVVM原理MVVM是一种用于构建用户界面的软件架构模式,它的名称代表着三个组成部分:Model(模型)、View(视图)和ViewModel(视图模型)。MVVM的主要目标是将应用程序的UI与其底层数据模型分离,通过数据绑定实现数据和UI的自动同步,从而降低代码的耦合度,提高应用程序的可维护性和可测试性。MVVM框架......
  • Nginx Ingress Contoller 通过 Envoy 代理和 Jaeger 进行分布式追踪(二)
    1、概述在《应用程序通过Envoy代理和Jaeger进行分布式追踪(一)》一文中,我们详细介绍了单个应用程序如何通过Envoy和Jaeger实现链路追踪的过程。然而,单独追踪单个应用程序的链路在实际场景中往往显得不够有意义。因此,在本文中,我们将进一步扩展链路追踪范围,演示如何将Ng......
  • SpringBoot复习:(55)在service类中的方法上加上@Transactional注解后,Spring底层是怎么生
    SpringBootrun方法代码如下:可以看到它会调用refreshContext方法来刷新Spring容器,这个refreshContext方法最终会调用AbstractApplicationContext的refresh方法,代码如下如上图,refresh方法最终会调用finisheBeanFactoryInitialization方法,代码如下:从上图可以看出,它最终会调用preIn......
  • 多级反向代理[Squid]下获取客户端真实IP地址
    在很多应用下都可能有需要将用户的真实IP记录下来,这时就要获得用户的真实IP地址,在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr(),这种方法在大部分情况下都是有效的。但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了。这段时间在做IP统计的......
  • LVS负载均衡之DR模式构建
    ※实验环境(1)系统:centos7.9(2)虚拟机:4台centos7.9,1台作为nfs共享服务器(NFS共享服务搭建步骤)一、负载调度器配置(1)关闭selinux、firewalld、NetworkManager#关闭selinuxsed-i's/SELINUX=enforcing/SELINUX=disabled/'/etc/selinux/config#关闭firewalldsystemctlstopfirewalld......
  • LVS负载均衡之DR模式构建
    ※实验环境(1)系统:centos7.9(2)虚拟机:4台centos7.9,1台作为nfs共享服务器(NFS共享服务搭建步骤)一、负载调度器配置(1)关闭selinux、firewalld、NetworkManager#关闭selinuxsed-i's/SELINUX=enforcing/SELINUX=disabled/'/etc/selinux/config#关闭firewalldsystemctlstopfirewalld......
  • 【Python】代理池针对ip拦截破解
    代理池是一种常见的反反爬虫技术,通过维护一组可用的代理服务器,来在被反爬虫限制的情况下,实现数据的爬取。但是,代理池本身也面临着被目标网站针对ip进行拦截的风险。本文将详细介绍代理池针对ip拦截破解的方法,包含相关代码实现:1.代理池的ip拦截问题代理池在实现反反爬虫的过程中......
  • 代理IP:跨界电商数据搜集的智能引擎
    跨界电商要实现在全球市场的有效布局,首要任务便是收集全球范围内的市场信息,竞争对手数据,以及消费者需求趋势。而这正是代理IP发挥作用的领域。多地区数据采集:代理IP技术允许企业模拟不同地区的IP地址,从而实现在全球范围内的多地区数据采集。这使得企业能够准确地了解各地的市场情......
  • 【Java设计模式005】代理模式
    概述大家好,个人gzh是大猪和小猪的小家,我们的gzh是朝阳三只大明白,满满全是干货,分享近期的学习知识以及个人总结(包括读研和IT),跪求一波关注,希望和大家一起努力、进步!!由于一些特定原因某些对象不适合或者不能直接引用目标对象,这时就可以使用代理模式。代理模式为目标对象提供一个代理以......
  • 使用QGIS切片,使用Nginx反向代理本地瓦片,并在QGIS加载图层
    使用QGIS切片(以tif为例)新建QGIS工程(.qgz)将tif文件拖到图层区打开工具箱-->栅格工具-->生成XYZ瓦片(目录)设置参数:坐标范围、层级、瓦片格式、输出目录等,点击运行输出目录不选则默认会生成到C盘的临时目录运行完毕后记录出现这段文字,关闭对话框,点击右下角路径可以预览使用......