摘要:什么是代理模式代理模式,类似于明星的经纪人,想要拜访明星,需要先通过经纪人的沟通。不同于装饰器,那种动态加载一个对象,可以说在代理模式当中,代理是早已既定的。又称单一功能原则,面向对象五个基本原则之一。
什么是代理模式
代理模式,类似于明星的经纪人,想要拜访明星,需要先通过经纪人的沟通。而在JS当中,如果想访问一个类,需要通过另一个类来间接访问 。不同于装饰器,那种动态加载一个对象,可以说在代理模式当中,代理是早已既定的。
别人眼中的代理
再拿最常遇到的收快递这一个社会行为举例吧。
很早之前,我们收发快递都是直接和快递员交互的,例如:
而现在,加入了代理之后,可以通过第三方替我们接收快递,即:
这是生活当中一个非常常见的例子,可以说代理的存在,大大的便利了“我”这个对象。下面就让我们在程序中看看代理是如何方便“我”的。
程序做这样一件事,即根据不同的快递类型,来进行不同的操作(执行不同的函数),那么在没有引进代理之前,写法可能是这个样子。
无代理:
class getDelivery { constructor() { } gets(a) { let fn1 = () => { setTimeout(() => { //some fns of fn1 console.log(`获取快递有:${a}`) }, 1000) } let fn2 = () => { setTimeout(() => { //some fns of fn2 console.log(`获取快递有:${a}`) }, 2000) } let fn3 = () => { setTimeout(() => { //some fns of fn3 console.log(`获取快递有:${a}`) }, 3000) } let deliver = {"中通": fn1, "EMS": fn2, "顺丰": fn3}[name]; return deliver(); } } getDelivery.prototype.proxyGets("中通")
定义一个类,上面的gets函数去判断不同的快递类型,然后去执行相对应的操作。
现在,当我们引入代理模式之后,代码可能是这样的:
代理:
class getDelivery { constructor() { } gets(a) { console.log(`获取快递有:${a}`) } } class proxy extends getDelivery { constructor() { super(); } proxyGets(name) { let fn1 = () => { setTimeout(() => { //some fns of fn1 super.gets("中通快递") }, 1000) } let fn2 = () => { setTimeout(() => { //some fns of fn2 super.gets("EMS") }, 2000) } let fn3 = () => { setTimeout(() => { //some fns of fn3 super.gets("顺丰") }, 3000) } let deliver = {"中通": fn1, "EMS": fn2, "顺丰": fn3}[name]; return deliver(); } } proxy.prototype.proxyGets("中通")
(ps:本代码仅用于代理模式的示例,每次调用函数重新声明fn1等方法是不对的)
ok,这两种方法都会得到这样的结果:
而后者在代码上还多了一些,但为什么这里还是推荐使用后面这种模式来写代码呢?
首先介绍一个面向对象设计原则,单一职责原则。
又称单一功能原则,面向对象五个基本原则(SOLID)之一。它规定一个类应该只有一个发生变化的原因。所谓职责是指类变化的原因。如果一个类有多于一个的动机被改变,那么这个类就具有多于一个的职责。而单一职责原则就是指一个类或者模块应该有且只有一个改变的原因。
而在本例中,我们并不关心是什么快递,关心的只是接到快递触发的结果,或者说接到快递后,执行的任务才是getDelivery 这个类的核心,至于中间的过程,应该交给专门处理他的类来判别。
第二个原则:开放封闭原则
开放封闭原则(OCP,Open Closed Principle)是所有面向对象原则的核心。软件设计本身所追求的目标就是封装变化、降低耦合,而开放封闭原则正是对这一目标的最直接体现。其他的设计原则,很多时候是为实现这一目标服务的,例如以Liskov替换原则实现最佳的、正确的继承层次,就能保证不会违反开放封闭原则。
还以接收快递为例,比如有一天,接收快递的形势变了,或者说,根本不需要判断是什么快递,可以随时接收,那么proxy 这个类其实就没有用了,此时我们可以直接调用getDelivery这个类。但是,如果以第一种写法的话,那就是无路可退了,只能去原对象中去删掉相对应的逻辑。当代码复杂程度变高的话,高耦合的程序,会让人非常恶心。
代理模式,在实践当中还可以应用于缓存ajax异步数据,惰性加载等等方面,本文不详细讲解,仅作抛砖引玉的入门参考。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/91712.html
摘要:注意事项声明函数时候处理业务逻辑区分和单例的区别,配合单例实现初始化构造函数大写字母开头推荐注意的成本。简单工厂模式使用一个类通常为单体来生成实例。 @(书籍阅读)[JavaScript, 设计模式] 常见设计模式 一直对设计模式不太懂,花了一下午加一晚上的时间,好好的看了看各种设计模式,并总结了一下。 设计模式简介 设计模式概念解读 设计模式的发展与在JavaScript中的应用 ...
摘要:在中构造器的典型特点就是首字母大写,我们通过原对象代理列表格式去创建对象创建的这个对象我们称之为代理对象。就是原对象是当前的属性名是代理对象。理解为明星的经理人消极怠工原封不动地转告外界的信息给明星本身。但是要注意与是两个不同的对象。 ES6之Proxy proxy的中文有代理的意思。在其他的程序设计语言中这个单词也具有类似的含义。 它是什么 Proxy是一个构造器。在js中构造器的典...
摘要:享元模式通过分析应用程序的对象,将其解析为内在数据和外在数据,减少对象数量,从而提高程序的性能。通过这种方式进行事件绑定,可以减少事件处理程序的数量,这种方式叫做事件委托,也是运用了享元模式的原理。事件处理程序是公用的内在部分,每个菜单项各 github 全文地址 : YOU-SHOULD-KNOW-JS JavaScript设计模式之外观模式 概念 外观模式:为一组复杂子系统接口提...
摘要:今天说一下,单一职责原则。比如,接口的地址本来已经很完美了,但是你的是处女座最讨厌处女座非要给路由添加几个以保证后台数据的安全。为了过年,我会选择使用,因为不知道处女座以后会做出什么傻事来。此时的使用动态织入后,可以完美的解决处女座。 在设计模式中,有着几条视为黄金原则,设计模式都是围绕黄金原则,对代码或者说是架构设计做出一些相应的调整,久而久之,GoF 4人组,发现其实有些设计思想可...
阅读 3574·2021-11-24 09:39
阅读 2355·2021-11-15 11:37
阅读 2118·2021-11-11 16:55
阅读 4926·2021-10-14 09:43
阅读 3605·2021-10-08 10:05
阅读 2967·2021-09-13 10:26
阅读 2244·2021-09-08 09:35
阅读 3505·2019-08-30 15:55