维基百科对代理模式的解释是:
代理模式(英语:Proxy Pattern)是程式設計中的一種設計模式。
所謂的代理者是指一個類別可以作為其它東西的介面。代理者可以作任何東西的介面:網路連接、記憶體中的大物件、檔案或其它昂貴或無法複製的資源。
著名的代理模式例子為參照計數(英语:reference counting)指標物件。
當一個複雜物件的多份副本須存在時,代理模式可以結合享元模式以減少記憶體用量。典型作法是建立一個複雜物件及多個代理者,每個代理者會參照到原本的複雜物件。而作用在代理者的運算會轉送到原本物件。一旦所有的代理者都不存在時,複雜物件會被移除。
接下来我们以一个实例来说明
案例引入
A类用户:可读、可写、可编辑、可删除
B类用户:可读、可写、可编辑
C类用户:可读、可写
D类用户:只读
我们现在需要对这些类用户做权限分配
那么一般的做法是在用户的各种行为中加入权限的判断,有权限的就通过,无权限的则输出警告:
function user(name, classs) { this.name = name; this.classs = classs; } user.prototype = { read: function () { console.log('读取成功'); } , write: function () { if (this.classs != 'D') { console.log('写入成功'); } else { console.warn('无权限写入'); } } , edit: function () { if (this.classs === 'A' || this.classs === 'B') { console.log('编辑成功'); } else { console.warn('无权限编辑'); } } , delete: function () { if (this.classs === 'A') { console.log('删除成功'); } else { console.warn('无权限删除') } } }
看起来好像没什么问题,貌似很好用,但是实际的开发中,不管是用户行为的设计(读取写入删除等),还是用户权限的分配往往都是非常复杂的,如果按照这种写法到了后期可能就会带来一些维护上的不便,我们需要将行为的设计和权限的分配分离开来,这个时候就可以使用代理模式对以上代码进行优化。
构建用户类:
function User(name, classs) { this.name = name; this.classs = classs; }
创建用户行为:
User.prototype = { getname: function () { return this.name; } , getclasss: function () { return this.classs; } , read: function () { console.log('读取成功'); } , write: function () { console.log('写入成功'); } , edit: function () { console.log('编辑成功'); } , delete: function () { console.log('删除成功'); } }
行为权限的分配:
function User_work(user){ this.user=user; } User_work.prototype={ getuser:function(){ return this.user; } , read: function () { return this.user.read(); } , write: function () { if(this.user.getclasss()!='D'){ return this.user.write(); } console.warn('无权限写入'); } , edit: function () { if(this.user.getclasss()==='B'||this.user.getclasss()==='A'){ return this.user.edit(); } console.warn('无权限编辑'); } , delete: function () { if(this.user.getclasss()==='A'){ return this.user.delete(); } console.warn('无权限删除') } }
接下来各个用户就可以开始工作了
new User_work(new User('likeke','C')).delete();//无权限删除 new User_work(new User('likeke','C')).write();//写入成功 new User_work(new User('likeke','C')).edit();//无权限编辑
当然,我们也可以创建一个统一的函数来简化上面调用的操作
function startWork(name,classs){ if(name && classs){ return new User_work(new User(name,classs)); } }
开始工作:
startWork('likek','B').delete();//无权限删除 startWork('likek','B').edit();//编辑成功 startWork('likek','B').write();//写入成功 startWork('likek','B').read();//读取成功
现在,如果我们需要修改用户的某种行为细节,那么只需要修改User类的原型里面的对应一项;如果我们需要对用户某种行为的权限分配或者越权处理做修改,就只需要修改User_work类的原型中对应的那一项。