代码改变世界

大话设计模式:代理模式 C#

2018-04-11 18:16  天才卧龙  阅读(665)  评论(1编辑  收藏

学无止境,精益求精

十年河东,十年河西,莫欺少年穷

学历代表你的过去,能力代表你的现在,学习代表你的将来

所谓代理模式就是你去委托一个人帮你干一件事!例如:你委托我帮你谈恋爱,你委托我帮你陪你媳妇儿逛街,你委托我帮你陪你女朋友回家过年!等等吧!这些事情有需求,请找我,电话:XXX,微信:XXX,QQ:XXX...

首先看看代理模式的 UML 类图:

上图中:RealSubject 代表的是你,Proxy 代表的是我,Subject 是你委托我做的一些事情。就拿你委托我陪你媳妇儿逛街来说,你告诉我要帮你媳妇儿买裙子,买鞋子,买零食等等,这些事情可以看成上图的抽象类 Sbuject 中的抽象方法。而我作为你的代理,我可以把你给我交代给我的事情不完全做,也就是说我可以不给你媳妇儿买零食。当然,我也可以偷偷背着你给你媳妇买玫瑰花。总之,作为代理的我可以全做,也可以部分做,亦可以偷偷趁机多做一点,给你媳妇儿献殷勤,说不定将来的某一天你媳妇儿就归我了!哈哈哈 ~_~

呵呵,调皮了点,言归正传!

那么咱们来看看C#实现代码模式的基础代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    /// <summary>
    /// 抽象接口类
    /// </summary>
    abstract class Subject
    {
        public abstract void Request();
    }
    /// <summary>
    /// 真是实体类
    /// </summary>
    class RealSubject: Subject
    {
        public override void  Request()
        {
             Console.WriteLine("真实的请求");
        }
    }
    /// <summary>
    /// 代理类
    /// </summary>
    class Proxy: Subject
    {
        RealSubject realSubject;
        public override void  Request()
        {
             if (realSubject==null)
            {
                realSubject= new RealSubject();
            }
            realSubject.Request();
        }
    }
    /// <summary>
    /// 客户端代码
    /// </summary>
    class Program
    {
        public static void Main(string[] args)
        {
            Proxy proxy= new Proxy();
            proxy.Request();

            Console.Read();
        }
    }
}
View Code

在此,为了让大家更深刻的了解代理模式,鄙人引用下别人的叙述,如下:

说起代理模式的时候,我顺便给大家说说我十一假期干嘛去了,但愿不会被打死(你们这是嫉妒我)

十一的时候呢,跟着我女朋友去她家了,从北京坐了十个小时的高铁到了广州,然后又辗转半天才到女朋友家,一开门我就把准备了好几天的话一口气对着她妈说完了,只见我这未来岳母一脸懵逼的看着我,然后来了句"!@#$%^&&*%",卧槽,这下轮到我懵逼了,此时只听我女朋友淡淡的来了一句"我妈不会说普通话,只会说粤语",MDZZ,你早说啊,害我提前准备了两天的说辞全白费了,然后在那呆了四五天,基本的套路就是我跟她爸妈的交流都是她爸妈先问,然后她翻译成普通话,然后我回答,她再添油加醋的翻译成粤语,好蛋疼。
针对以上情况,这不刚好是代理模式吗?

上述叙述博客原文:https://www.cnblogs.com/liaidai/p/5956883.html

下面看看使用代码怎么实现上述的情景:

首先委托者和被委托者要有一个公共的交流类(意思就是说,被委托者需要帮委托者做什么的类)

    /// <summary>
    /// UML 类图中的 Subject
    /// </summary>
    public abstract class Communication
    {

        public abstract void talkHome();//谈家庭

        public abstract void talkWork();//谈工作

        public abstract void talkMarry();//谈结婚

        public abstract void talkOther();//谈其他

    }

其次,无论是委托者我还是被委托者我的女盆友都必须继承这个类:

    /// <summary>
    /// 我,被代理的人
    /// </summary>
    public class Me : Communication
    {
        public override void talkHome()
        {
            Console.WriteLine("我说我的家庭");
        }


        public override void talkWork()
        {
            Console.WriteLine("我说我的工作");
        }


        public override void talkMarry()
        {
            Console.WriteLine("我说结婚");
        }


        public override void talkOther()
        {
            Console.WriteLine("我说其他");
        }

    }

    /// <summary>
    /// 我的女盆友,也是我的代理人
    /// </summary>
    public class MyGirlFriend : Communication
    {
        private Me me;

        public MyGirlFriend()
        {
            if (me == null)
            {
                this.me = new Me();
            }
        }


        public override void talkHome()
        {
            me.talkHome();
            Console.WriteLine("GF翻译加工我的家庭");
        }


        public override void talkWork()
        {
            me.talkWork();
            Console.WriteLine("GF翻译加工我的工作");
        }


        public override void talkMarry()
        {
            me.talkMarry();
            Console.WriteLine("GF翻译加工关于结婚");
        }


        public override void talkOther()
        {
            me.talkOther();
            Console.WriteLine("GF翻译加工关于其他");
        }
    }
        static void Main(string[] args)
        {
            MyGirlFriend GF = new MyGirlFriend();
            GF.talkHome();
            GF.talkMarry();
            GF.talkOther();
            GF.talkWork();
            //
            Console.ReadKey();
        }

最后,我们看看程序的最后执行如下:

OK,其实代理模式的UML类图很简单,实现起来亦是很简单。

但是,我们学习设计模式,最重要的并不是会编写UML类图展现的代码,而应该学会该设计模式的应用场景!

那么,代理模式的应用场景是什么呢?

 代理模式效果与适用场景

       代理模式是常用的结构型设计模式之一,它为对象的间接访问提供了一个解决方案,可以对对象的访问进行控制。代理模式类型较多,其中远程代理、虚拟代理、保护代理等在软件开发中应用非常广泛。

 模式优点

       代理模式的共同优点如下:

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

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

       此外,不同类型的代理模式也具有独特的优点,例如:

       (1) 远程代理为位于两个不同地址空间对象的访问提供了一种实现机制,可以将一些消耗资源较多的对象和操作移至性能更好的计算机上,提高系统的整体运行效率。

       (2) 虚拟代理通过一个消耗资源较少的对象来代表一个消耗资源较多的对象,可以在一定程度上节省系统的运行开销。

       (3) 缓冲代理为某一个操作的结果提供临时的缓存存储空间,以便在后续使用中能够共享这些结果,优化系统性能,缩短执行时间。

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

 

 模式缺点

       代理模式的主要缺点如下:

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

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

 

模式适用场景

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

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

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

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

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

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

关于代理模式更加深入的剖析,大家可参考以下博客:

代理模式剖析:http://jiangshuiy.iteye.com/blog/1333558

代理模式剖析:https://www.cnblogs.com/zoupeiyang/archive/2009/05/26/1489333.html

OK,截止到这儿,代理模式也就在幽默中讲完了!

@陈卧龙的博客