设计模式之-代理模式

定义:

代理模式(Proxy Pattern) :给某一个对象提供一个代理,并由代理对象控制对原对象的引用。代理模式的英 文叫做Proxy或Surrogate,它是一种对象结构型模式。

代理模式参与者

  • Subject:定义了RealSubject和Proxy的共用接口,这样就在任何使用RealSubject的地方都可以使用Proxy。
  • RealSubject:定义Proxy所代表的真实实体。
  • Proxy:保存一个引用使得代理可以访问实体,并提供一个与Subject的接口相同的接口,这样代理就可以用来代替实体。

代理模式基本代码

Subject类:

namespace ProxyPattern.BasicStructure
{
    abstract class Subject
    {
        public abstract void Request();
    }
}

RealSubject类:

namespace ProxyPattern.BasicStructure
{
    class RealSubject : Subject
    {
        public override void Request()
        {
            Console.WriteLine($"真实的请求:{this.GetType()}");
        }
    }
}

Proxy类:

namespace ProxyPattern.BasicStructure
{
    class Proxy : Subject
    {
        Subject subject;

        public override void Request()
        {
            if (subject == null)
            {
                subject = new RealSubject();
            }
            subject.Request();
        }
    }
}

客户端调用代码:

    static void Main(string[] args)
    {
        try
        {
            {//BasicStructure
                Proxy proxy = new Proxy();
                proxy.Request();
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        Console.ReadKey();
    }

结果如下:

用代理模式实现代理买手机

场景模拟:最近手机越来越不好使了,准备买部IPhone XS,听说香港买比较便宜,刚好有个朋友要去香港,听说香港的准备叫他帮我从香港带一部回来。

BuyHandset(购买手机)类——Subject类

namespace ProxyPattern.SituationSimulation
{
    /// <summary>
    /// 购买手机类
    /// </summary>
    abstract class BuyHandset
    {
        public abstract void BuyAppleHandset();
    }
}

RealBuyHandset(真实购买手机)类——RealSubject类

namespace ProxyPattern.SituationSimulation
{
    class RealBuyHandset : BuyHandset
    {
        public override void BuyAppleHandset()
        {
            Console.WriteLine($"{this.GetType().Name}购买了一部苹果手机!");
        }
    }
}

BuyHandsetProxy(购买手机代理)类——Proxy类

namespace ProxyPattern.SituationSimulation
{
    class BuyHandsetProxy : BuyHandset
    {
        BuyHandset buyHandset;

        public override void BuyAppleHandset()
        {
            if (buyHandset == null)
            {
                buyHandset = new RealBuyHandset();
            }
            buyHandset.BuyAppleHandset();
        }
    }
}

客户端调用代码:

    static void Main(string[] args)
    {
        try
        {
            {//SituationSimulation
                BuyHandsetProxy proxy = new BuyHandsetProxy();
                proxy.BuyAppleHandset();
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        Console.ReadKey();
    }

结果如下:

优点:

代理模式的优点

  • 代理模式能够协调调用者和被调用者,在一定程度上降低了系 统的耦合度。
  • 远程代理使得客户端可以访问在远程机器上的对象,远程机器 可能具有更好的计算性能与处理速度,可以快速响应并处理客户端请求。
  • 虚拟代理通过使用一个小对象来代表一个大对象,可以减少系 统资源的消耗,对系统进行优化并提高运行速度。
  • 保护代理可以控制对真实对象的使用权限。

缺点:

代理模式的缺点

  • 由于在客户端和真实主题之间增加了代理对象,因此 有些类型的代理模式可能会造成请求的处理速度变慢。
  • 实现代理模式需要额外的工作,有些代理模式的实现 非常复杂。

适用环境:

根据代理模式的使用目的,常见的代理模式有以下几种类型:

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

总结:

  • 在代理模式中,要求给某一个对象提供一个代理,并由代理对象控制对原对象的引用。代理模式的英文叫做Proxy或Surrogate,它是一种对象结构型模式。 - 代理模式包含三个角色:抽象主题角色声明了真实主题和代理主题的共同接口;代理主题角色内部包含对真实主题的引用,从而可以在任何时候操作真实主题对象;真实主题角色定义了代理角色所代表的真实对象,在真实主题角色中实现了真实的业务操作,客户端可以通过代理主题角色间接调用真实主题角色中定义的方法。 - 代理模式的优点在于能够协调调用者和被调用者,在一定程度上降低了系统的耦合度;其缺点在于由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢,并且实现代理模式需要额外的工作,有些代理模式的实现非常复杂。远程代理为一个位于不同的地址空间的对象提供一个本地的代表对象,它使得客户端可以访问在远程机器上的对象,远程机器可能具有更好的计算性能与处理速度,可以快速响应并处理客户端请求。- 如果需要创建一个资源消耗较大的对象,先创建一个消耗相对较小的对象来表示,真实对象只在需要时才会被真正创建,这个小对象称为虚拟代理。虚拟代理通过使用一个小对象来代表一个大对象,可以减少系统资源的消耗,对系统进行优化并提高运行速度。 - 保护代理可以控制对一个对象的访问,可以给不同的用户提供不同级别的使用权限。

 

源代码地址:https://github.com/houzhenhuang/DesignPattern

posted @ 2019-02-22 11:23  黄厚镇  阅读(131)  评论(0编辑  收藏  举报