• .NET代理模式


     当我们需要使用的对象很复杂或者需要很长时间去构造,这时就可以使用代理模式(Proxy)。例如:如果构建一个对象很耗费时间和计算机资源,代理模式(Proxy)允许我们控制这种情况,直到我们需要使用实际的对象。一个代理(Proxy)通常包含和将要使用的对象同样的方法,一旦开始使用这个对象,这些方法将通过代理(Proxy)传递给实际的对象。

      一些可以使用代理模式(Proxy)的情况:

      1、一个对象,比如一幅很大的图像,需要载入的时间很长。

      2、一个需要很长时间才可以完成的计算结果,并且需要在它计算过程中显示中间结果

      3、一个存在于远程计算机上的对象,需要通过网络载入这个远程对象则需要很长时间,特别是在网络传输高峰期。

      4、一个对象只有有限的访问权限,代理模式(Proxy)可以验证用户的权限

      代理模式(Proxy)也可以被用来区别一个对象实例的请求和实际的访问,例如:在程序初始化过程中可能建立多个对象,但并不都是马上使用,代理模式(Proxy)可以载入需要的真正的对象。

      这是一个需要载入和显示一幅很大的图像的程序,当程序启动时,就必须确定要显示的图像,但是实际的图像只能在完全载入后才可以显示!这时我们就可以使用代理模式(Proxy)。

      这个代理模式(Proxy)可以延迟实际图像的载入,直到它接收到一个paint请求。在实际图像的载入期间我们可以通过代理模式(Proxy)在实际图像要显示的位置预先载入一个比较小、简单的图形。

    一个称职的代理人是什么呢?显然它不仅要向客户提供供应者完善的服务,也要对这种服务进行有效的控制,同时又要方便客户使用。设计模式中的代理模式正式要充当这个代理人,那么.NET中该如何实现该代理人呢?且看下文。

    代理模式是GOF23种设计模式中结构型模式之一,意图是为其他对象提供一种代理以控制对这个对象的访问,UML类图如下:

    图1

    由此图也许我们看不出代理模式意图要表达真实意思,那么我们在看一副图,如下:

    图2

    由此图联系其意图,我们不难理解代理模式的意图了。图中aClient是客户,要访问aRealSubject对象,然而由于某种原因我们需要对这种访问进行控制。因此我们引入了代理aProxy,代理aProxy提供了一个虚拟的aRealSubject供aClient访问,并且能够对这种访问进行控制,而对aClient来说,这个虚拟的对象与真实的对象完全一样。

      上面我们明白了什么是代理模式,那么在.NET中如何实现呢?根据图1也许你能很快写出一段示例代码,<C#设计模式>一书中就是这么实现的。但是示例代码并不能解决我们的实际问题,我们也并不需要关注UML图中的每一个细节,更不一定必须按UML图中的结构类实现。那么在实际.NET开发中该如何实现代理模式呢?幸运的是微软在.NET中为我们提供了实现代理模式的基本框架,我们稍作改动即可在代码中直接使用。

      .NET中与实现代理模式有关的类有以下几个:

    1.   ContextBoundObject:定义所有上下文邦定类的基类;
    2.   RealProxy:提供代理的基本功能;
    3.   ProxyAttribute:指示对象类型需要自定义代理;

      如果我们要定义一个需要被代理的类,那么仅需要从ContextBoundObject继承即可,如下:

    1 [ProxyTag]
    2 public  class RealClass : ContextBoundObject {
    3     public RealClass() {
    4         Console.WriteLine("构造一个RealClass!");
    5     }
    6 }

      如果要为RealClass定义代理,那么需要从RealProxy继承自己的代理类,并重载Invoke方法:

    01 public override IMessage Invoke(IMessage msg) {
    02     //自定义构造对象前进行处理
    03     PreProcess(msg);
    04     IMessage retMsg=null;
    05     if (msg is IConstructionCallMessage) {
    06         IConstructionCallMessage ccm = (IConstructionCallMessage)msg;
    07  
    08         retMsg = EnterpriseServicesHelper.CreateConstructionReturnMessage(ccm, (MarshalByRefObject)this.GetTransparentProxy());
    09     }
    10     //自定义构造对象后进行处理
    11     PostProcess(retMsg);
    12     return retMsg;
    13 }

      在定义完代理类后,需要定义二者关联的Attribute,才能完成需要的代理,此时需要从ProxyAttribute继承实现自己的标签,并重载CreateInstance方法:

    01 public override MarshalByRefObject CreateInstance(Type serverType) {
    02     MarshalByRefObject mobj = base.CreateInstance(serverType);
    03     if (aspectManaged) {
    04         RealProxy realProxy = new ProxyClass(serverType, mobj);
    05         MarshalByRefObject retobj = realProxy.GetTransparentProxy() as MarshalByRefObject;
    06         return retobj;
    07     }
    08     else {
    09         return mobj;
    10     }
    11 }

      经过以上步骤,我们就完成了一个可以直接使用的代理类。写一行测试代码验证一下我们例子。

    1 try {
    2     RealClass pc = new RealClass();
    3 }
    4 catch (Exception ex) {
    5     Console.WriteLine(ex.Message);
    6 }

    运行结果为:

    根据类的定义,我们在创建一个RealClass实例时会输出“构造一个RealClass!”,而实际测试结果如上。由此可知代理RealProxy达到了我们预期的目的。

    注:

      1,阅读此文需要理解代理模式,如有不明的地方,请留言。

    参考资料:

    -------------------------------------------------------------------------------------------------------------------------------------------------
    数据库优化
    数据库教程
    数据库实战经验分享博客

    百度云下载

    评测


  • 相关阅读:
    Servlet的生命周期?
    C++图结构的图结构操作示例
    如何从google play下载app应用,直接下载apk
    C# Socket异步聊天例子
    三极管饱和,放大,截止电压判断
    java中的浮点(float)运算
    微软2014校园招聘笔试试题
    软件开发中的资源控制问题学习
    linux mount命令学习
    17、Spring Boot普通类调用bean【从零开始学Spring Boot】
  • 原文地址:https://www.cnblogs.com/longle/p/2270341.html
Copyright © 2020-2023  润新知