深入理解设计模式(23):代理模式

一、引言

  我们都知道,数据库连接是很珍贵的资源,频繁的开关数据库连接是非常浪费服务器的CPU资源以及内存的,所以我们一般都是使用数据库连接池来解决这一问题,即创造一堆等待被使用的连接,等到用的时候就从池里取一个,不用了再放回去,数据库连接在整个应用启动期间,几乎是不关闭的,除非是超过了最大闲置时间。

  但是在程序员编写程序的时候,会经常使用connection.close()这样的方法,去关闭数据库连接,而且这样做是对的,所以你并不能告诉程序员们说,你们使用连接都不要关了,去调用一个其他的类似归还给连接池的方法吧。这是不符合程序员的编程思维的,也很勉强,而且具有风险性,因为程序员会忘的。

  解决这一问题的办法就是使用代理模式,因为代理模式可以替代原有类的行为,所以我们要做的就是替换掉connection的close行为。

二、什么是代理模式

代理模式——就是给某一个对象提供一个代理,并由代理对象控制对原对象的引用。在一些情况下,一个客户不想或者不能直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。例如电脑桌面的快捷方式就是一个代理对象,快捷方式是它所引用的程序的一个代理。

三、代理模式的结构

  (1) Subject(抽象主题角色):它声明了真实主题和代理主题的共同接口,这样一来在任何使用真实主题的地方都可以使用代理主题,客户端通常需要针对抽象主题角色进行编程。

(2) Proxy(代理主题角色):它包含了对真实主题的引用,从而可以在任何时候操作真实主题对象;在代理主题角色中提供一个与真实主题角色相同的接口,以便在任何时候都可以替代真实主题;代理主题角色还可以控制对真实主题的使用,负责在需要的时候创建和删除真实主题对象,并对真实主题对象的使用加以约束。通常,在代理主题角色中,客户端在调用所引用的真实主题操作之前或之后还需要执行其他操作,而不仅仅是单纯调用真实主题对象中的操作。

(3) RealSubject(真实主题角色):它定义了代理角色所代表的真实对象,在真实主题角色中实现了真实的业务操作,客户端可以通过代理主题角色间接调用真实主题角色中定义的操作。

四、代理模式和装饰模式的异同

代理模式和装饰模式的代码实现方式很相同,主要不同点是代理模式关注与被代理对象行为的控制,然而装饰模式关注于在一个对象上动态的添加方法。

代理模式可以对客户端隐藏被代理对象的具体实现,代理模式的时候常常是在一个代理类中创建一个对象的实例,当使用装饰模式的时候,将原始对象转为一个参数传递给装饰者的构造器中

代理模式强调的是限制,装饰模式强调的是增强

五、代理模式和委托

代理:是把一些事情交给某人帮忙去完成。

委托:是当某件事情发生的时候,顺便干某件事情。委托就相当于一个触发器罢了。

六、代理模式的种类

在实际开发过程中,代理类的实现比上述代码要复杂很多,代理模式根据其目的和实现方式不同可分为很多种类,其中常用的几种代理模式简要说明如下:

(1) 远程代理(Remote Proxy):为一个位于不同的地址空间的对象提供一个本地的代理对象,这个不同的地址空间可以是在同一台主机中,也可是在另一台主机中,远程代理又称为大使(Ambassador)。

(2) 虚拟代理(Virtual Proxy):如果需要创建一个资源消耗较大的对象,先创建一个消耗相对较小的对象来表示,真实对象只在需要时才会被真正创建。

(3) 保护代理(Protect Proxy):控制对一个对象的访问,可以给不同的用户提供不同级别的使用权限。

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

(5) 智能引用代理(Smart Reference Proxy):当一个对象被引用时,提供一些额外的操作,例如将对象被调用的次数记录下来等。

七、代理模式的应用场景

代理模式的类型较多,不同类型的代理模式有不同的优缺点,它们应用于不同的场合:

       (1) 当客户端对象需要访问远程主机中的对象时可以使用远程代理。

       (2) 当需要用一个消耗资源较少的对象来代表一个消耗资源较多的对象,从而降低系统开销、缩短运行时间时可以使用虚拟代理,例如一个对象需要很长时间才能完成加载时。

       (3) 当需要为某一个被频繁访问的操作结果提供一个临时存储空间,以供多个客户端共享访问这些结果时可以使用缓冲代理。通过使用缓冲代理,系统无须在客户端每一次访问时都重新执行操作,只需直接从临时缓冲区获取操作结果即可。

       (4) 当需要控制对一个对象的访问,为不同用户提供不同级别的访问权限时可以使用保护代理。

       (5) 当需要为一个对象的访问(引用)提供一些额外的操作时可以使用智能引用代理。

八、代理模式的优缺点

优点:

  (1) 能够协调调用者和被调用者,在一定程度上降低了系统的耦合度。

(2) 客户端可以针对抽象主题角色进行编程,增加和更换代理类无须修改源代码,符合开闭原则,系统具有较好的灵活性和可扩展性。

缺点:

  (1) 由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢,例如保护代理。

(2) 实现代理模式需要额外的工作,而且有些代理模式的实现过程较为复杂,例如远程代理。

九、代理模式的实现

class SchoolGirl            //定义 女孩类
    {
        private string name;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
    }
//抽象主题类声明了真实主题类和代理类的公共方法,它可以是接口、抽象类或具体类,客户端针对抽象主题类编程,一致性地对待真实主题和代理主题,interface IGiveGift        //创建一个送礼物的接口
    {
        void GiveDolls();
        void GiveFlowers();
        void GiveChocolate();
    }
//真实主题类继承了抽象主题类,提供了业务方法的具体实现,
class Pursuit:IGiveGift     //追求者类,使用送礼物的接口
    {
        SchoolGirl mm;          //要追求女孩的名字
        public Pursuit(SchoolGirl mm)
        {
            this.mm = mm;
        }
        public void GiveDolls()
        {
            Console.WriteLine(mm.Name+"送你洋娃娃");
        }
        public void GiveFlowers()
        {
            Console.WriteLine(mm.Name + "送你花");
        }
        public void GiveChocolate()
        {
            Console.WriteLine(mm.Name + "送你巧克力");
        }
    }
//代理类也是抽象主题类的子类,它维持一个对真实主题对象的引用,调用在真实主题中实现的业务方法,在调用时可以在原有业务方法的基础上附加一些新的方法来对功能进行扩充或约束,class Proxy : IGiveGift         //定义代理模式,也用送礼物的接口
    {
        Pursuit gg;
        public Proxy(SchoolGirl mm)     //区别在于,代替追求者 送礼物
        {
            gg=new Pursuit(mm);
        }
        public void GiveDolls()
        {
            gg.GiveDolls();
        }
        public void GiveFlowers()
        {
            gg.GiveFlowers();
        }
        public void GiveChocolate()
        {
            gg.GiveChocolate();
        }
    }
class Program
    {
        static void Main(string[] args)
        {
            SchoolGirl mm = new SchoolGirl();
            mm.Name = "hanmeimei";

            Proxy daili = new Proxy(mm);

            daili.GiveDolls();
            daili.GiveFlowers();
            daili.GiveChocolate();
        }
    }
(0)

相关推荐

  • 结构型模式之代理模式

    在有些情况下,一个客户不能或者不想直接访问另一个对象,这时需要找一个中介帮忙完成某项任务,这个中介就是代理对象. 定义与特点 由于某些原因需要给某对象提供一个代理以控制对该对象的访问.这时,访问对象不 ...

  • Android插件化开发基础之静态代理模式

    一 Proxy模式 意图: 为其他对象提供一种代理以控制这个对象的访问. 适用性: l  远程代理( Remote Proxy ): 为一个对象在不同的地址空间提供局部代表. l  虚代理(Virtu ...

  • 大话设计-代理模式

    记录大话设计学习过程. 代理模式:代理者为其他对象提供代理,以控制对真实对象的访问. 用户调用代理者,代理者通过真实的对象引用让对象去做事情.但是代理者可以附加一些功能,然后才让真实对象去做事情. 代 ...

  • PHP设计模式之代理模式

    PHP设计模式之代理模式 代理人这个职业在中国有另外一个称呼,房产经济人.保险经济人,其实这个职业在国外都是叫做房产代理或者保险代理.顾名思义,就是由他们来帮我们处理这些对我们大部分人来说都比较生疏的 ...

  • [PHP小课堂]PHP设计模式之代理模式

    [PHP小课堂]PHP设计模式之代理模式 关注公众号:[硬核项目经理]获取最新文章 添加微信/QQ好友:[DarkMatterZyCoder/149844827]免费得PHP.项目管理学习资料

  • 设计模式之☞代理模式

    一.代理模式的作用 将主要业务与次要业务进行松耦合的组装 二.代理模式本质 监控行为的特征 例子: <input type="button" onclick="处理 ...

  • 设计模式之代理模式(proxy pattern)

    代理模式的本质是一个中间件,主要目的是解耦合服务提供者和使用者.使用者通过代理间接的访问服务提供者,便于后者的封装和控制.是一种结构性模式. 1.目的 为外部调用者提供一个访问服务提供者的代理对象. ...

  • 设计模式(十三)——代理模式

    设计模式(十三)——代理模式

  • 无废话设计模式(11)结构型模式--代理模式

    0-前言 代理模式定义:为其他对象提供一种代理以控制对这个对象的访问. 1-实现 1-1.简单UML图: 1-2.代码实现 //1.抽象父类 abstract class Actor { public ...

  • 【设计模式】牛掰格拉斯的代理模式

    代理的本质 无论任何时候,只要谈到设计模式,大脑中一定要蹦出这四个字"活学活用". 要想对某个事物做到活学活用,必须要对它足够了解,甚至要剖析到本质才行. 总是会有些人说,我干嘛要 ...

  • Java设计模式——代理模式

    代理模式 学习目标 掌握代理模式的应用场景和实现原理. 应用场景 保护目标对象:客户并不知道对象是如何实现具体业务功能的,只要调用代理对象的接口就行了. 增强目标对象:在实现目标对象的业务功能之前或者 ...

  • 23种设计模式之原型模式

    原型模式 1.基本介绍 1)原型模式(Prototype模式)是指:用原型实例指定创建对象的种类,并通过拷贝这些原型,创建新的对象. 2)原型模式是一种创建型设计模式,允许一个对象再创建另一个可定制的 ...