【第1505期】谈谈代理
前言
挺喜欢这种用通俗,现实中的案例来说明。今日早读文章由饿了么@繁星投稿分享。
正文从这开始~~
首先分享一个有趣的思维实验:
缸中之脑: 假设你此刻,并不在你认为你存在的地方,事实上,你只是邪恶天才的科学实验的对象。你的大脑已经被切离你的身体,放进了实验室里一个盛有维持大脑存活的营养液的缸中。大脑的神经末梢连接在一部超级计算机上,计算机提供给大脑一切你日常生活中的感觉,这使你感到一切正常
你是真实存在的吗?你还是“你”吗?你所了解的世界是你想象的虚构的东西,还是邪恶的科学家构建出来的幻觉?这听起来也许是噩梦般的场景。但你无法以绝对的确定说它是虚假的
即使我们不能肯定,外部世界是如何出现在我们的感官中的,但至少我们可以肯定的是,因为每一次我们怀疑这件事时,必然存在一个“我”正在做出怀疑,所以我们的确是存在着的
这就是“我思故我在”的著名哲学理论
虽然无法证明我们活在真实还是虚拟的世界,但是“思考能力”至少可以证明我们是真实存在的,也间接的说明人最具核心价值的能力就是思考
作为前端从业者,我很多次面试都会问面试者一个问题:什么是 Promise ? 面试者给的答案很多:有说如何实现的;有说解决了什么问题的;有介绍使用姿势的;但绝大多数人都没给出一个令人满意的答案,或者说绝大多数人在学习技术知识的时候缺乏主动思考能力
计算机科学的发展和进步是离不开对人类活动的借鉴的,所以当我们在计算机术语里看到一个生活中也出现的词语的时候,要去生活中抽象和寻找本质,拿 Proxy 来说,生活中我们常见的有代理人和代理商:
代理人:打官司要委托律师作为诉讼代理人,主体是原告和被告,但是他们打官司的经验和法律知识不如律师专业,所以需要律师这个代理体;在外地工作,如果需要在老家办理证件需要委托亲人作为代理人,因为本人不在家
代理商:餐饮代理加盟、本地生活公司(饿了么、美团)的区域代理商,游戏代理等,主体提供基础能力,代理商基于这些在自己代理的区域去经营。为什么需要代理商呢?说好听点是其在当地有资源、关系、人脉,说不好听就是地头蛇、政府关系户等,但本质是他们有能力降低运营成本,提升效率
从上面生活中的代理可以总结出其核心要点:主体、代理体、代理体存在的原因和要去做的事。但是,这里存在的原因描述的有点废话嫌疑,再深入思考,这些原因本质是代理体对主体能力的补充和加强。所以最终核心要点有:主体、补充或加强主体能力的代理体和要去做的事,简单说就是在主体和要做的事情之间加一层,用来补充或加强能力
拿这个模型来解释”缸中之脑“,我们的躯体只是提供行动能力的代理体,真正的主体我是那个存储着记忆信息、拥有属于个人的思维和思考能力的灵魂。假如未来科技可以将灵魂安放在能力更强大的机器上,人类是否可以成为为所欲为的大力士飞来飞去呢?当我们沉浸在游戏的世界里,此时代理你的不是你的躯体,而是那个游戏角色,而此时你拥有游戏角色的各种技能来完成游戏任务。游戏的本质是提供了一个灵魂可以安放的代理体及代理体所在的环境,让人可以更容易取得成就获得快乐
拿这个模型来理解你在计算机世界里见到的代理:
Promise 是对当前不确定、但未来会确定的值的代理体,Promise 可以让开发者摆脱嵌套地狱
VPN(正向代理) 是一个网络访问者的代理体,通过其访问网络可以隐藏访问者,更安全。或者有能力访问到正常访问不了的内部网络(翻墙也属于此类)
CDN(反向代理) 是静态资源服务器的代理体,通过其获取资源可以降低主体服务器压力,提升性能
负载均衡服务器(反向代理)是业务服务器的代理体,通过其可以将请求均衡分发给处理业务的服务器,这样通过对业务服务器进行扩容就能处理更多高并发请求
代理模式:为一个对象提供一个代理对象,并由代理对象控制对原对象的访问。这种控制访问能力能细化到:对象属性的获取、赋值,是否可遍历;对象方法的调用,可以在这个方法调用前后做前后置处理等
例如:
let validator = {
set: function(obj, prop, value) {
if (prop === 'age') {
if (!Number.isInteger(value)) {
throw new TypeError('The age is not an integer');
}
if (value > 200) {
throw new RangeError('The age seems invalid');
}
}
// The default behavior to store the value
obj[prop] = value;
// Indicate success
return true;
}
};
let person = new Proxy({}, validator);
person.age = 100;
console.log(person.age); // 100
person.age = 'young'; // Throws an exception
person.age = 300; // Throws an exception
代理模式的核心是通过代理对象扩展对主体对象访问时的控制能力,Vue 和 Mobx 实现对数据变更监听的原理本质就是代理模式
关于 AOP
在 深入浅出 Javascript Decorators 和 AOP 编程 一文中有对 AOP 编程做了介绍,也详细讲解了 Javascript Decorators 提供的 AOP 能力,Proxy 也可以提供 AOP 能力,区别是:Proxy 具有被代理对象的控制权,AOP 切入功能也是基于这种控制能力的。而 Decorator 只能为类属性增加一层装饰,以加强被装饰属性的功能,最终作用于实例化出来的对象上
关于本文
作者:@繁星
原文:https://github.com/rainjay/blog/issues/9
最后,为你推荐