设计模式初探-代理模式

是什么

代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问。

生活是一切东西的起源,在生活中也到处能看到代理模式的影子。 明星有经纪人作为代理,要联系明星的档期其实是和经纪人联系,经纪人联系好之后,再有明星负责签约、演出。

想想平时工作中也有这种例子,每个小组都要发周报,组长负责周报的收集, 总监通过周报查看每个成员的工作情况,而不是每个成员都直接向总监汇报。

甚至古代也能找到类似的例子,挟天子以令诸侯,曹操和汉献帝的关系,也有代理模式的影子。

为什么

大概对代理模式有个模糊的概念了,那为什么要存在代理模式?

单一职责原则

想一想,明星为什么要有经纪人。经纪人可以负责帮助明星安排各种工作,对明星包装炒作等等。而明星自己只专注于演出。如果所有工作都交给明星自己完成,一个再高效再厉害的人估计也得忙疯了。

相应的,在面向对象设计原则中有单一职责原则,它规定一个类应该只有一个发生变化的原因。如果一个类承担了太多职责,这个类就会变得越来越庞大,难以维护。

对象无法被直接操作

还是看下明星和经纪人这个例子。作为一个大牌明星,不可能把自己的联系方式公开给大家。那别人怎么联系明星呢?经纪人这时候就起作用了,通过联系经纪人相当于间接的和明星有了联系。

对应程序设计里的场景,比如文档里面装了很大一张图片,在文档被打开的时候要加载里面的内容一起打开,但是如果等加载完这个大图片再打开文档用户要等太久,所以我们可以为这个图片设置一个代理,让代理慢慢打开这个图片而不影响文档本来的功能。

实际场景

权限管理

var User = {
    post: function () {
        console.log('发文章');
    },
    remove: function () {
        console.log('删除文章');
    }
}

var ProxyUser = {
    post: function () {
        if (有权限) {
            User.post();
        }

        console.log('没有权限发文章');
    },
    remove: funtion () {
        if (有权限) {
            User.remove();
        }

        console.log('没有权限删除文章');
    }
}

上面是一个简单的权限管理的例子。将权限管理的部分抽象出一个代理来实现。有人可能会说,代码本来可以写下面这么简单:

var User = {
    post: function () {
        if (有权限) {
            console.log('发文章');
        }

        console.log('没有权限发文章');
    },
    remove: funtion () {
        if (有权限) {
            console.log('删除文章');
        }

        console.log('没有权限删除文章');
    }
}

还非要搞个代理瞎折腾?

想想我们平时工作中越来越庞大的文件,想想每次改动一个小问题要折腾着把一个文件上千行代码看一遍,再想想前面提到的单一职责原则。我们发现这样分解其实是更易于维护的。用户类本身并不关注权限。

想想假设以后有个场景,不再需要权限控制了,使用了代理模式的场景,我们要做的只是把ProxyUser删了,接口换成User就完了。没有使用代理模式的,则是费尽心思改动这个User类。

再想想,之后我们权限规则有变动,只需要调整Proxy就好了,而并不关注用户到底是如何发文章,如何删除文章的。这也正是遵循了单一职责原则带来的好处。

loading态

我们经常遇到这样的场景,发一个ajax请求获得一堆数据,请求过程中展示loading态,数据回来隐藏loading,用请求回来的数据初始化模块。

这也可以用代理模式。

    var Mod = {
        init: function (data) {
            // 主逻辑
        }
    }

    var ProxyLoading = {
        init: function (mod) {
            showLoading();

            if (请求成功) {
                hideLoading();
                mod.init(data);
            } else {
                hideLoading();
            }
        } 
   }

   ProxyLoading.init(Mod);

简单的抽出一个Proxy来处理loading做的事情。

小结

代理模式远非这么简单,本文也只是作者此时此刻的理解,希望可以起到抛砖引玉的作用,不对之处还望各位大侠指正~~

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏张善友的专栏

LINQ via C# 系列文章

LINQ via C# Recently I am giving a series of talk on LINQ. the name “LINQ via C...

3005
来自专栏陈仁松博客

ASP.NET Core 'Microsoft.Win32.Registry' 错误修复

今天在发布Asp.net Core应用到Azure的时候出现错误InvalidOperationException: Cannot find compilati...

5228
来自专栏我和未来有约会

Silverlight第三方控件专题

这里我收集整理了目前网上silverlight第三方控件的专题,若果有所遗漏请告知我一下。 名称 简介 截图 telerik 商 RadC...

4395
来自专栏C#

DotNet加密方式解析--非对称加密

    新年新气象,也希望新年可以挣大钱。不管今年年底会不会跟去年一样,满怀抱负却又壮志未酬。(不过没事,我已为各位卜上一卦,卦象显示各位都能挣钱...)...

5908
来自专栏大内老A

The .NET of Tomorrow

Ed Charbeneau(http://developer.telerik.com/featured/the-net-of-tomorrow/) Exciti...

38610
来自专栏一个爱瞎折腾的程序猿

sqlserver使用存储过程跟踪SQL

USE [master] GO /****** Object: StoredProcedure [dbo].[sp_perfworkload_trace_s...

2850
来自专栏java 成神之路

使用 NIO 实现 echo 服务器

5567
来自专栏转载gongluck的CSDN博客

cocos2dx 打灰机

#include "GamePlane.h" #include "PlaneSprite.h" #include "BulletNode.h" #include...

7126
来自专栏魂祭心

原 canvas绘制clock

5094
来自专栏pangguoming

Spring Boot集成JasperReports生成PDF文档

由于工作需要,要实现后端根据模板动态填充数据生成PDF文档,通过技术选型,使用Ireport5.6来设计模板,结合JasperReports5.6工具库来调用渲...

1.4K7

扫码关注云+社区