代理模式就是一个对象来控制对另一个对象的访问。与另一个对象有相同的接口,把方法传递给对象。可以把本体的实例化推迟到真正需要的时候。在处理需要长时间才能载入本体的时候适用。
代理模式就是对访问的控制,代理对象与本体有相同的接口,实际工作由本体去做,然而代理对象是分派任务的对象。
var Book = function(isbn, title, author){};
var PublicLiarary = function(books){
this.catalog = {};
for(var i = 0, len = books.length; i < len; i++){
this.catalog[books[i].getIsbn()] = {book:books[i],available:true};
}
};
PublicLiarary.prototype = {
findBooks:function(searchString){
var results = [];
for(var isbn in this.catalog){
if(!this.catalog.hasOwnProperty(isbn)) continue;
if(searchString.match(this.catalog[isbn].getTitle())||
searchStringmatch(this.catalog[isbn].getAuthor())){
results.push(this.catalog[isbn]);
}
}
return results;
},
checkoutBook:function(book){
var isbn = book.getIsbn();
if(this.catalog[isbn]){
if(this.catalog[isbn].available){
this.catalog[isbn].available = false;
return this.catalog[isbn];
}else{
throw new Error();
}
}else{
throw new Error();
}
},
returnBook:function(book){
var isbn = book.getIsbn();
if(this.catalog[isbn]){
this.catalog[isbn].available = true;
}else{
throw new Error();
}
}
};
var PublicLibraryProxy = function(catalog){
this.library = new PublicLibrary(catalog);
};
PublicLibraryProxy.prototype = {
findBooks:function(searchString){
return this.library.findBooks(searchString);
},
checkoutBook:function(book){
return this.library.checkoutBook(book);
},
returnBook:function(book){
return this.library.returnBook(book);
}
};
这里通过PublicLibraryProxy代理PublicLiarary。
如果PublicLiarary实例化很慢,我们则在需要时实例化,就是虚拟代理
var PublicLibraryVirtualProxy = function(catalog){
this.library = null;
this.catalog = catalog;
};
PublicLibraryVirtualProxy.prototype = {
_initializeLibrary:function(){
if(this.library == null){
this.library = new PublicLibrary(this.catalog);
}
},
findBooks:function(searchString){
this._initializeLibrary();
return this.library.findBooks(searchString);
},
checkoutBook:function(book){
this._initializeLibrary();
return this.library.checkoutBook(book);
},
returnBook:function(book){
this._initializeLibrary();
return this.library.returnBook(book);
}
};
远程代理:用于访问另一个环境中的对象,远程对象一直存在,任何时候都可访问。在JS中不适用。
保护代理:JS不能控制对本体的访问
代理模式与装饰者模式的比较
装饰者模式会对包装对象的功能进行补充或者修改,代理模式只是控制访问,不会对本体的方法做改动。
如果有些类或者对象的创建开销比较大,而且不需要实例化完成以后立即访问数据,使用虚拟代理。
如果有某种远程资源,为该资源提供所有功能对应的方法,使用远程代理。