通俗易懂设计模式解析——代理模式

2019-09-29 15:55:17 浏览数 (2)

前言

  今天讲的是结构型设计模式中的最后一个,这个模式也就是代理模式,在前段时间我写的一篇关于正向代理和反向代理的文章。虽说此代理非彼代理。但是代理一词还是具有相似的含义的。这里我们继续使用文章中的代购一个例子来讲述一下代理模式吧,人不方便去购买哪些物品,这时就有一个中间人,他来购买。他代替我去购买。他也就充当了那个代理的职责。我们继续往下看吧。

代理模式介绍

一、来由

  在软件系统的开放中,有一些对象存在,但是直接访问会给使用者带来一些麻烦,或者使用起来不那么方便,这是就是需要一个代理对象来中间起到关键作用。通过这个代理对象进行访问,以来解决这些问题。这也就是代理模式。

二、意图

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

三、案例图

四、代理模式代码示例

看上面的案例图,我们发现代理模式包含以下部分:

抽象角色:定义代理角色和真实角色的公共接口,这样来说使用真实角色的地方就可以使用代理角色。

代理角色:包含对真实角色的引用,这样可以操作真实角色,代理角色不仅仅只是调用真实角色,也会执行其他的操作。

真实角色:定义了代理角色所代表的真实角色。

这里我们使用的是一个代理进行代购的案例来进行讲述,让我们一起看看如何实现的吧:

代码语言:javascript复制
namespace Proxy_Pattern
{
    class ProxyPattern
    {
    }
    #region 抽象角色——抽象需要做的事情的方法
    public abstract class Buy
    {
        public abstract void BuyFun(string Name);
    }
    #endregion

    #region 真实角色——实现抽象的方法
    public class RealBuy : Buy
    {
        public override void BuyFun(string Name)
        {
            Console.WriteLine($"帮我购买{Name}");
        }
    }
    #endregion

    #region 代理角色——代购
    public class ProxyBuy : Buy
    {
        public RealBuy realBuy;
        public ProxyBuy()
        {
            realBuy = new RealBuy();
        }
        public override void BuyFun(string Name)
        {
           var flag= this.AllowBuy(Name);
            if (!flag)
            {
                Console.WriteLine("违禁品不允许购买"); 
            }
            else
            {
                realBuy.BuyFun(Name);
                Recording(Name);
            }
        }

        /// <summary>
        /// 代理模式中的额外操作。例如购买的东西,不可能啥东西都买。需要对购买的东西进行检查
        /// </summary>
        /// <param name="Name">购买的东西</param>
        /// <returns></returns>
        public bool AllowBuy(string Name)
        {
            if (Name!="违禁品")
            {
                return true;
            }
            return false;
        }
        /// <summary>
        /// 对购买的东西进行记录
        /// </summary>
        /// <param name="Name"></param>
        public void Recording(string Name)
        {
            Console.WriteLine($"这次代购购买了{Name}");
        }
    }
    #endregion
}
代码语言:javascript复制
namespace Proxy_Pattern
{
    class Program
    {
        static void Main(string[] args)
        {
            //初始化代理对象
            Buy buy = new ProxyBuy();
            //代理对象进行处理事务
            buy.BuyFun("化妆品");

            buy.BuyFun("违禁品");
        }
    }
}

使用场景及优缺点

  不管是使用怎样的代理,都是在软件系统中增加一个中间层次,这种方式对于解决一些复杂问题或者对象之间的问题提供了较大方便。代理模式又划分了许多的类型,待会下面我们会一一介绍的。代理模式并不要求保持各个类之间的接口的一致性,代理模式的重点是间接控制,中间层次管理。

一、使用场景

根据代理模式的职责我们可以分为以下的使用场景:

远程代理:为两个不同地址的对象信息代理,典型例子就是客户端与服务之间。客户端调用服务。

虚拟代理:根据需要创建一个资源消耗较大的对象,使得对象在需要的时候才会被调用。

Copy-on-Write 代理:属于虚拟代理的一种,把复制或者克隆拖延到客户端需要的时候才执行。

保护(Protect or Access)代理:控制对象的访问,提供不同级别使用的不同的访问权限。

Cache代理:为一个目标的结果提供一个临时的保存空间,以便于多个客户端可以使用这些结果

防火墙(Firewall)代理:保护目标不受恶意侵犯

智能引用(Smart Reference)代理:当一个对象被调用引用的时候,提供一些额外的操作,可以把调用的次数或调用的位置记录下来。

二、优点

1、增加了中间代理层,降低了客户端与对象之间的耦合度

2、中间的代理对对象增加了保护层次,同时也可以增加一些额外的操作例如权限控制、智能化

3、职责清晰明了。抽象—真实—代理

三、缺点

1、由于增加了代理对象,有些情况可能会造成代理之间的请求变慢

2、由于增加了代理对象,增加了一些额外的工作,造成了系统的复杂度

总结

  到这里设计模式中的结构型的各个设计模式我就介绍完了。最后一个代理模式,理解起来也是相对简单的。重点理解代理一词。再回首、看看我们也将看完了设计模式三个部分中的两个部分。创建型——解决对象创建的问题,对象之间解耦的问题。结构型——主要解决的是类和对象之间的结构问题。这里又包括类结构和对象结构问题。这里我们再来回顾一下结构型设计模式及其重点吧

适配器模式——注重转换接口,使接口匹配、达到复用的目的

桥接模式——注重接口和实现的分离,注重多维度的变化。

装饰模式——注重稳定接口的前提下对对象进行扩展

组合模式——注重将一对多转换为一对一,树型结构层次的关系

外观模式——简化接口和客户端之间的调用依赖关系

享元模式——注重最小单元对象的共享

代理模式——增加中间层次实现控制


    不要为它的结束而哭,应当为它的开始而笑。

C#设计模式系列目录

0 人点赞