持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第7天
介绍
为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用
在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式
使用场景
-
远程代理:为一个对象在不同的地址控件提供局部代表
-
虚拟代理:将开销大的对象延迟到需要时才创建
-
Copy-on-Write 代理
-
保护(Protect or Access)代理
-
Cache代理:为开销大的运算结果提供缓存
-
防火墙(Firewall)代理
-
同步化(Synchronization)代理
-
智能引用(Smart Reference)代理:取代了简单的指针,在访问对象执行一些附加操作,比如计算一个对象的引用次数
应用实践
职责明确
-
抽象角色:通过接口或抽象类声明真实角色实现的业务方法。
-
代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。
-
真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。
实现
应用里需要显示一张尺寸很大的图片,位于远端服务器。我们用一些前端框架的Image这个控件类去显示图片。如果直接调用控件类的代码
image.setSrc(“xxxxxx”), 那么在这张具体的图片真正加载到本地之前,UI上显示一片空白,这个用户体验不好。
我们日常生活中其实已经能感觉到,很多优秀的前端应用,在加载大尺寸图片或者执行其他费时的后台操作时,前台都会有一些动画效果。
var loadingImg = (function () {
var img = document.createElement("img");
document.body.appendChild(img);
return {
setImg: function (src) {
img.src = src
}
}
})()
var proxyImg = (function () {
//img创建
var image = new Image();
image.onload = function () {
loadingImg.setImg(image.src); }
return {
setSrc: function (src) {
loadingImg.setImg("1.png"); //需要加载的图片
image.src = src;
}
}
})()
var src = "https://xxxxx.png";
proxyImg.setSrc(src);
汇总
优点特性
-
分离目标对象 : 代理模式能将代理对象 与 真实被调用的目标对象分离;
-
降低耦合: 在一定程度上 ,降低了系统耦合性,扩展性好;
-
保护目标对象: 代理类 代理目标对象的业务逻辑 ,客户端直接与代理类交互,客户端 与 实际的目标对象之间没有关联 ;
-
增强目标对象 : 代理类 可以 在 目标对象基础上 ,添加新的功能 ;
缺点弊端
-
由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。
-
实现代理模式需要额外的工作,有些代理模式的实现非常复杂。
-
一旦接口增加方法,目标对象与代理对象都要维护。