设计模式之代理模式(十)

一、引出模式

代理,在生活我我们非常常见。比如在中学时期,总追过女孩子吧!身为码农的我们,没追过也没关系,总看过别人追过女孩子吧!这里出现了3个重要人物,甲想追求乙,但甲又不认识乙,幸好乙的闺蜜丙是甲的小学同学,于是呢,甲就通过丙给乙传递一些纸条,情书之类的。在这里面同学丙就充当着一个代理的角色,甲无法直接找到乙说话,只能通过丙给乙传递消息。

二、认识模式

1.定义:

代理模式为目标对象提供一种代理,并由该代理对象控制对这个目标对象的访问。

2.模式结构和说明

Subject:目标接口,定义代理和具体目标对象的接口,这样就可以在任何地方使用具体目标对象的地方使用代理对象。

RealSubject:具体的目标对象,真正实现目标接口的功能。

Proxy:代理对象,主要有如下功能:

* 实现和具体的目标对象一样的接口,这样可以使用代理来代替具体的目标对象

* 保存一个指向具体目标对象的引用,可以在需要时调用具体的目标对象。

* 可以控制对具体目标对象的访问,并可以负责创建和删除它。

3.示例代码

 class Program
    {
        static void Main(string[] args)
        {
            Subject subject = new Proxy(new RealSubject());
            subject.Request();
 
            Console.ReadKey();
        }
    }
 
    /// <summary>
    /// 定义具体的目标对象和代理公有接口
    /// </summary>
    public abstract class Subject
    {
        public abstract void Request();
    }
 
    /// <summary>
    /// 具体的目标对象,是真正被代理的对象
    /// </summary>
    public class RealSubject : Subject
    {
        public override void Request()
        {
            //执行真正要实现的功能
            Console.WriteLine("调用真实对象");
        }
    }
 
    /// <summary>
    /// 代理对象
    /// </summary>
    public class Proxy : Subject
    {
        //持有被代理的具体目标对象
        private RealSubject subject = null;
 
        //注入具体被代理的目标对象
        public Proxy(Subject subject)
        {
            this.subject = (RealSubject) subject;
        }
 
        public override void Request()
        {
            //转调之前可以做一些事情,比如权限判断等
 
            //转调具体目标对象的方法
            subject.Request();
 
            //转调之后也可以做一些事情
        }
    }

三、理解模式

1.模式功能:

代理模式通过创建一个代理对象,用这个对象去代表真实对象,当客户端操作这个给代理对象时,实际上功能最终还是会有真实对象来实现,只不过是通过代理操作的。

正是因为代理对象夹在客户端与真实对象之间,相当于中转站,所以在中转前后可以做很多事情,比如权限判断。

2.代理分类:

* 远程代理:为一个位于不同的地址空间的对象提供一个局域代表对象。这个不同的地址空间可以是在本机器中,也可是在另一台机器中。远程代理又叫做大使(Ambassador)。

* 虚拟代理:根据需要创建一个资源消耗较大的对象,使得此对象只在需要时才会被真正创建。

* Copy-on-Write代理:虚拟代理的一种。把复制(克隆)拖延到只有在客户端需要时,才真正采取行动。

* 保护代理:控制对一个对象的访问,如果需要,可以给不同的用户提供不同级别的使用权限。

* Cache代理:为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果。

* 防火墙代理:保护目标,不让恶意用户接近。

* 同步化代理:使几个用户能够同时使用一个对象而没有冲突。

* 智能指引:当一个对象被引用时,提供一些额外的操作,比如将对此对象调用的次数记录下来等。

在所有种类的代理模式中,虚拟(Virtual)代理、远程(Remote)代理、智能引用代理(Smart Reference Proxy)和保护(Protect or Access)代理是最为常见的代理模式。

3.具体目标对象和代理对象的关系

从模式图来看,好像一个具体目标类就有一个代理类,其实不是这样的。如果代理类能完全通过接口来操作它所代理的目标对象,那么代理对象就不需要知道具体的目标对象,这样就无需为每一个具体目标对象都创建一个代理类。

4.保护代理细说

保护代理是一种控制对原始对象访问的代理,多用于对象应该有不同的访问权限的时候。保护代理会检查调用者是否具有请求所必需的访问权限,如果没有,就不会调用目标对象,从而实现对目标对象的保护。

示例:现在有个订单系统,一旦订单被创建,那么只有创建人才能需改和删除订单。

class Program
    {
        static void Main(string[] args)
        {
            #region 保护代理

            #endregion

            OrderApi orderApi = new ProxyOrder(new Order("设计模式", 100, "zxj"));
            orderApi.SetProductName("哈哈哈", "zxj");

            Console.ReadKey();
        }
    }


    #region 保护代理

    /// <summary>
    /// 订单接口
    /// </summary>
    public abstract class OrderApi
    {
        public abstract void SetProductName(string ProductName, string ProductUser);
    }

    /// <summary>
    /// 订单
    /// </summary>
    public class Order : OrderApi
    {
        /// <summary>
        /// 产品名称
        /// </summary>
        public string ProductName { get; set; }

        /// <summary>
        /// 产品数量
        /// </summary>
        public int ProductNum { get; set; }

        /// <summary>
        /// 操作员
        /// </summary>
        public string ProductUser { get; set; }

        public Order(string PeoductName, int ProductNum, string ProductUser)
        {
            this.ProductName = PeoductName;
            this.ProductNum = ProductNum;
            this.ProductUser = ProductUser;
        }

        public override void SetProductName(string ProductName, string ProductUser)
        {
            throw new NotImplementedException();
        }
    }

    public class ProxyOrder : OrderApi
    {
        private Order order;

        public ProxyOrder(Order order)
        {
            this.order = order;
        }

        public override void SetProductName(string ProductName, string ProductUser)
        {
            if (order.ProductName != null && order.ProductUser.Equals(ProductUser))
            {
                Console.WriteLine("{0}可以修改", ProductUser);
            }
            else
            {
                Console.WriteLine("{0}无权修改", ProductUser);
            }
        }
    }
    #endregion

5.模式特点

*  远程代理:隐藏了一个对象存在不同的地址空间的事实。

*  虚代理:可以根据需要创建“大”对象,只要到必须创建对象的时候,虚代理才会创建对象。

*  保护代理:可以在访问一个对象的前后,附加执行很多操作,除了权限控制之外,还可以进行很多业务,也就是说,可以通过代理来给目标对象增加功能。

*  智能指引:和保护代理类似,可以在访问一个对象前后附加其他操作,如果存有保护性质的,就算保护代理,其他就算是智能指引。

6.代理模式的选用

*  需要为一个对象在不同的地址空间提供局部代表的时候,可以使用远程代理。

*  需要按照需要创建开销很大的时候,可以使用虚代理。

*  需要控制原始对象的访问的时候,可以使用保护代理。

*  需要在访问对象执行一些附加操作的时候,可以使用智能代理。

7.模式本质 

控制对象访问

代理模式通过代理目标对象,把代理对象插入到客户和目标对象之间,从而为客户和目标引入一定的间接性。正是这个间接性,给力代理对象很大的活动空间,可以在目标对象前后,附加很多操作,从而实现新的功能或是扩展。

从实现哈桑看,代理模式主要使用对象的组合和委托,尤其是在静态代理的实现里面。也可以采用对象继承的方式来实现代理,比如上面的保护代理示例

8.相关模式

*  代理模式与适配器模式

这两个模式有一定的相似性,它们都为另一个对象提供间接性访问,而且都是从自身以外的一个借口想这个对象转发请求。

但是在功能上,适配器模式主要用来解决接口之间不匹配的问题。它通常是为所适配的对象提供一个不同的接口;而代理模式会实现和目标对象相同的接口。

*  代理模式和装饰模式

这两个模式从实现上相似,都是在转掉调其他对象的前后执行一定的功能。

但是它们的功能和目的是不同的,装饰模式目的是为了让你不生成子类就可以给对象添加指着,也就是为了动态的添加功能;而代理模式的主要目的是控制对对象的访问。

posted @ 2013-11-29 12:07  烧点饭  阅读(607)  评论(0编辑  收藏  举报