代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问。
生活是一切东西的起源,在生活中也到处能看到代理模式的影子。 明星有经纪人作为代理,要联系明星的档期其实是和经纪人联系,经纪人联系好之后,再有明星负责签约、演出。
想想平时工作中也有这种例子,每个小组都要发周报,组长负责周报的收集, 总监通过周报查看每个成员的工作情况,而不是每个成员都直接向总监汇报。
甚至古代也能找到类似的例子,挟天子以令诸侯,曹操和汉献帝的关系,也有代理模式的影子。
大概对代理模式有个模糊的概念了,那为什么要存在代理模式?
想一想,明星为什么要有经纪人。经纪人可以负责帮助明星安排各种工作,对明星包装炒作等等。而明星自己只专注于演出。如果所有工作都交给明星自己完成,一个再高效再厉害的人估计也得忙疯了。
相应的,在面向对象设计原则中有单一职责原则,它规定一个类应该只有一个发生变化的原因。如果一个类承担了太多职责,这个类就会变得越来越庞大,难以维护。
还是看下明星和经纪人这个例子。作为一个大牌明星,不可能把自己的联系方式公开给大家。那别人怎么联系明星呢?经纪人这时候就起作用了,通过联系经纪人相当于间接的和明星有了联系。
对应程序设计里的场景,比如文档里面装了很大一张图片,在文档被打开的时候要加载里面的内容一起打开,但是如果等加载完这个大图片再打开文档用户要等太久,所以我们可以为这个图片设置一个代理,让代理慢慢打开这个图片而不影响文档本来的功能。
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就好了,而并不关注用户到底是如何发文章,如何删除文章的。这也正是遵循了单一职责原则带来的好处。
我们经常遇到这样的场景,发一个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做的事情。
代理模式远非这么简单,本文也只是作者此时此刻的理解,希望可以起到抛砖引玉的作用,不对之处还望各位大侠指正~~