首页 > 设计模式 > 初尝Proxy 模式

初尝Proxy 模式

一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。在软件系统中,有些对象有时候由于跨越网络或者其他的障碍,而不能够或者不想直接访问另一个对象,如果直接访问会给系统带来不必要的复杂性,这时候可以在客户程序和目标对象之间增加一层中间层,让代理对象来代替目标对象打点一切。

如果按照使用目的来划分,代理有以下几种:

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

意图

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

结构图

proxy结构图 初尝Proxy 模式

由于Proxy 的具体应用场景通常都比较复杂,这里没有太合适的代码例子。按照李建忠老师介绍的,在Web Service 中应该经常可以看到代理模式的影子。这里为了完整性,还是采用一种模拟远程调用的例子,来表达对Proxy 的使用。在2个应用程序的通信过程中,来实现对Proxy 的模拟。

一段代码:

using System;
using System.Reflection;

namespace Proxy
{
    class Program
    {
        static void Main(string[] args)
        {
            MathProxy proxy = new MathProxy();
            Console.WriteLine(" 2 + 3 = {0}",proxy.Add(2,3));
            Console.WriteLine(" 2 - 3 = {0}", proxy.Substract(2, 3));
            Console.WriteLine(" 2 * 3 = {0}", proxy.Mutiply(2, 3));
            Console.WriteLine(" 2 / 3 = {0}", proxy.Divide(2, 3));
        }
    }
    public interface IMath {
        double Add(double a, double b);
        double Substract(double a, double b);
        double Mutiply(double a, double b);
        double Divide(double a, double b);
    }
    public class Math : MarshalByRefObject, IMath {
        public double Add(double a,double b) {
            return a + b;
        }
        public double Substract(double a,double b) {
            return a - b;
        }
        public double Mutiply(double a,double b) {
            return a * b;
        }
        public double Divide(double a, double b) {
            return a / b;
        }
    }

    public class MathProxy:IMath {
        Math math;
        public MathProxy() {
            //开辟一个新的应用程序域
            AppDomain ad = AppDomain.CreateDomain("MathProxy New");
            //在新的域上调用Math这个类-模拟远程调用
            math=(Math)
            ad.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName,"Proxy.Math");
        }

        public double Add(double a,double b) {
            return math.Add(a,b);
        }
        public double Substract(double a,double b) {
            return math.Substract(a,b);
        }
        public double Mutiply(double a,double b) {
            return math.Mutiply(a,b);
        }
        public double Divide(double a, double b) {
            return math.Divide(a,b);
        }
    }

}

运行截图:

proxy运行截图 初尝Proxy 模式

  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.