大熊君说说JS与设计模式之------代理模式Proxy
一,总体概要
1,笔者浅谈
当我们浏览网页时,网页中的图片有时不会立即展示出来,这就是通过虚拟代理来替代了真实的图片,而代理存储了真实图片的路径和尺寸,这就是代理方式的一种。
代理模式是比较有用途的一种模式,而且变种较多(虚代理、远程代理、copy-on-write代理、保护代理、Cache代理、防火墙代理、同步代理、智能指引),应用场合覆盖从小结构到整个系统的大结构,
我们也许有代理服务器等概念,代理概念可以解释为:在出发点到目的地之间有一道中间层,意为代理。
代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。
咱们来看一个例子,如下:
1 function XiaoV(){ 2 this.talk = function(){ 3 console.log("狼猫老弟,不好意思上次的事,请多多谅解。") ; 4 } ; 5 } ; 6 function LangMao(){ 7 this.bb = new BigBear() ; 8 this.talk = function(){ 9 console.log("大熊君好啊,最忌忙什么那?") ; 10 this.bb.talk() ; 11 } ; 12 } ; 13 function BigBear(){ 14 this.xiaov = new XiaoV() ; 15 this.talk = function(){ 16 console.log("狼猫兄弟,中午没事一起吃顿饭聊聊天,那天我见到小v了,他优化和你说。。。。。。") ; 17 this.xiaov.talk() ; 18 } ; 19 } ; 20 function go(){ 21 new LangMao().talk() ; 22 } ;
小v和狼猫有点误会,由大熊君帮着缓和一下误会慢慢解除了。O(∩_∩)O哈哈哈~
二,源码案例参考
描述------地理编码对象模拟谷歌地图地理编码服务。在地理编码提供一个位置(在地球上的一个地方),它将返回它的纬度/经度(参数)。我们的地理编码可以解决只有4个位置,但在现实中有数以百万计,因为它涉及到国家,城市,街道。
程序员决定实施一个代理对象因为地理编码相对缓慢。代理对象叫做GeoProxy。它是已知的许多重复的要求(同一位置)来。加快速度GeoProxy缓存经常请求的位置。如果一个位置是不是已经缓存而是走到真实的地理编码服务和存储在缓存结果。
几个城市的位置查询,这些都为同一个城市。GeoProxy建立其缓存同时支持这些电话。最后GeoProxy<已处理了11个要求而不得不去请求只有3次。请注意,客户端程序不了解代理对象(它调用标准getlatlng方法相同的接口)。见代码如下:
GeoProxy于真实对象相同的接口以便在任何时刻都能代替真实对象完成特定操作,并且在其中间植入其他相关任务功能。
三,案例引入
注册普通用户:code为“001”
论坛管理者 :code为“002”
系统管理者 :code为“003”
游 客 :code为“000”
论坛开放了四个基础功能
1,发帖
2,帖子审核
3,清除帖子
4,留言
游客不具备任何操作权限,注册用户只能发帖,论坛管理者可以审核以及删帖操作,系统管理者具有所有功能权限。
这些权限划分和管理是使用Proxy完成的。
(1),创建用户实体类
1 function User(name,code){ 2 this.name = name ; 3 this.code = code ; 4 } ; 5 User.prototype = { 6 getName : function(){ 7 return this.name ; 8 } , 9 getCode : function(){ 10 return this.code ; 11 } , 12 post : function(){ 13 console.log("发帖子!") ; 14 } , 15 remove : function(){ 16 console.log("删除帖子!") ; 17 } , 18 check : function(){ 19 console.log("审核帖子!") ; 20 } , 21 comment : function(){ 22 console.log("回复帖子!") ; 23 } 24 } ;
(2),创建论坛类
1 function Forum(user){ 2 this.user = user ; 3 } ; 4 Forum.prototype = { 5 getUser : function(){ 6 return this.user ; 7 } , 8 post : function(){ 9 if(this.user.getCode() == "001" || this.user.getCode() == "003"){ 10 return this.user.post() ; 11 } 12 console.log("没权限发帖子!") ; 13 } , 14 remove : function(){ 15 if(this.user.getCode() == "002" || this.user.getCode() == "003"){ 16 return this.user.remove() ; 17 } 18 console.log("没权限删除帖子!") ; 19 } , 20 check : function(){ 21 if(this.user.getCode() == "002" || this.user.getCode() == "003"){ 22 return this.user.check() ; 23 } 24 console.log("没权限审核帖子!") ; 25 } , 26 comment : function(){ 27 if(this.user.getCode() == "003"){ 28 return this.user.comment() ; 29 } 30 console.log("没权限回复帖子!") ; 31 } 32 } ;
(3),创建客户端测试类
1 function ForumClient(){ 2 this.run = function(){ 3 new Forum(new User("bigbear","003")).check() ; // 审核帖子 4 } 5 } ;
以上例子中Forum于真实对象相同的接口以便在任何时刻都能代替真实对象完成特定操作,并且在其中间植入其他相关任务功能。
四,总结一下
抽象角色:声明真实对象和代理对象的共同接口。
代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。
真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。
代理模式的一个好处就是对外部提供统一的接口方法,而代理类在接口中实现对真实类的附加操作行为,从而可以在不影响外部调用情况下,进行系统扩展。也就是说,我要修改真实角色的操作的时候,尽量不要修改他,而是在外部在“包”一层进行附加行为,即代理类。
代理模式使用场景
当我们需要使用的对象很复杂或者需要很长时间去构造,这时就可以使用代理模式(Proxy)。例如:如果构建一个对象很耗费时间和计算机资源,代理模式(Proxy)允许我们控制这种情况,直到我们需要使用实际的对象。一个代理(Proxy)通常包含和将要使用的对象同样的方法,一旦开始使用这个对象,这些方法将通过代理(Proxy)传递给实际的对象。 一些可以使用代理模式(Proxy)的情况:
一个对象,比如一幅很大的图像,需要载入的时间很长。
一个需要很长时间才可以完成的计算结果,并且需要在它计算过程中显示中间结果
一个存在于远程计算机上的对象,需要通过网络载入这个远程对象则需要很长时间,特别是在网络传输高峰期。
一个对象只有有限的访问权限,代理模式(Proxy)可以验证用户的权限
哈哈哈,本篇结束,未完待续,希望和大家多多交流够沟通,共同进步(*^__^*) 嘻嘻……