为一个对象提供一个代理,以便控制对它的访问。
关键:提供一个替身对象来控制对该对象的访问,以满足需求。
保护代理和虚拟代理
- 保护代理:代理者替被代理者过滤掉某些请求,用于控制不同权限对目标对象的访问,在JavaScript中并不容易实现
- 虚拟代理: 把一些开销很大的对象,延迟到真正需要它的时候才去创建
虚拟代理实现图片预加载
Image对象提供setSrc接口
|
|
直接访问对image进行设置的时候,会有一定的加载时间。因此我们使用ProxyImage对象来对其进行占位设置,当图片加载成功的时候,才进行setSrc操作:
|
|
代理模式意义
- 保证每个对象或者函数的纯净,满足“单一职责原则”,图片进进行src设置,代理对象实现图片预加载功能
- 并不改变原对象的功能,但是为原对象满足了更多的功能,符合开放封闭原则。
接口一致性
代理和本体需保持接口的一致
- 用户可放心的请求代理
- 任何使用本体的地方都可替换成使用代理
假设代理或者本体都为一个方法,可以默认为一致的接口
应用,合并请求
通过代理模式,进行请求的合并,减少服务器压力
|
|
惰性加载
使用代理模式代理一个“假的接口”,当在想要真正的触发时,才去加载并执行代码:
|
|
缓存代理
缓存复杂计算
|
|
cal函数仅作相乘运算,缓存功能用proxyCal代理实现
同时,我们可以更加通用化,通过工厂模式创建代理
|
|
其他
- 防火墙代理: 控制网络资源的访问
- 远程代理:为一个对象在不同的地址空间提供局部代表
- 保护代理:用于对象应该有不同访问权限的情况
- 智能引用代理:取代了简单的指针,它在访问对象时执行一些附加操作,比如计算一个
对象被引用的次数。 - 写时复制代理:通常用于复制一个庞大对象的情况。写时复制代理延迟了复制的过程,
当对象被真正修改时,才对它进行复制操作。写时复制代理是虚拟代理的一种变体,DLL (操作系统中的动态链接库)是其典型运用场景。
其他语言实现
- RealSubject类,真实实体
- Proxy类,保存一个实体的引用,可以访问实体,并提供与实体相同的接口
- Subject类,定义了两个类的共用接口,以保证访问实体的地方同样也可以访问代理。
总结
代理模式其实就是为了为对象提供一个代理类,来进行更多的操作或行为,以保护原对象或者满足更多的需求,保持原对象的“纯净”,在javascript中其实很常见,我们不必刻意的考虑使用代理模式的必要性,只有当对象无法满足要求时,为其添加代理即可。