js 设计模式 第十四章 Proxy Pattern
来源:互联网 发布:老男孩linux运维 编辑:程序博客网 时间:2024/05/22 09:43
why?
1 如果某对象的创建比较耗资源,吃内存。一个方案,就是当用户真正调用对象的方法时,才让真实对象实例化。暴露给用户的是,那个真实对象的代理,它的创建不会消耗太多的资源,这里说的就是virtural proxy。
2 让网络上的数据,用起来像是本地数据。屏蔽网络请求、错误处理等复杂的底层处理。remote proxy 就是一个远程资源的代理。
how?
proxy 的核心是:proxy 实现真实对象的方法,他不会对真实对象的方法进行添、删、改。
what?
proxy 是对某个对象进行访问控制的对象,proxy 对象实现了同真实访问对象一样的接口,通过传递,最终还是真实的访问对象去实施相应的方法。proxy 对象不会添加和修改接口的方法(decorator 会修改或添加),也不会像facade那样简化接口。proxy 实现真实对象一样的接口,并直接传递给真实对象的方法
入门proxy
最简单的proxy 是不进行访问控制,它简单地把任何方法的调用,直接转换为真实对象的方法调用。这样的proxy 没有什么用途,但是却提供了一个基本的proxy 框架
var Publication = new Interface('Publication', ['getIsbn', 'setIsbn', 'getTitle','setTitle', 'getAuthor', 'setAuthor', 'display']);var Book = function(isbn, title, author) { ... } // implements Publication/* Library interface. */var Library = new Interface('Library', ['findBooks', 'checkoutBook', 'returnBook']);var PublicLibrary = function(books) { // implements Librarythis.catalog = {};for(var i = 0, len = books.length; i < len; i++) { this.catalog[books[i].getIsbn()] = { book: books[i], available: true }; }};PublicLibrary.prototype = { findBooks:function(searchString){},checkoutBook : function(book){},returnBook : function(book){}};/* PublicLibraryProxy class, a useless proxy. */var PublicLibraryProxy = function(catalog) { // implements Library 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 实现了同PublicLibrary 一样的接口。当proxy 实例化后,他同时也实例化了一个PublicLibrary 对象,将他作为一个属性。任何时候,当PublicLibraryProxy的方法调用的时候,他将最终调用的是PublicLibrary 对象的那个方法。
virtual proxy
这个例子用途不大,但是他的变种virtual Proxy 却是proxy 最常用的一种方式。virtual Proxy 适用场景是针对复杂、创建耗资源的对象。virtual proxy 将延迟真实对象的访问,直到对象的方法被访问。比如说:PublicLibrary 实例化很慢,这时用virtual proxy 来延迟加载
/* PublicLibraryVirtualProxy class. */var PublicLibraryVirtualProxy = function(catalog) { // implements Library this.library = null; this.catalog = catalog; // Store the argument to the constructor.};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);}};
PublicLibraryVirtualProxy 没有立即实例PublicLibrary 对象,他在构造函数中存储了参数,知道方法被调用时,才真正实例化对象。这样,如果方法一直没有被调用,这个兑奖就永远不会被创建。
remote proxy
remote proxy 用来封装远程数据,让用户使用远程数据的时候,像是使用本地数据一样。
一个remote proxy 的一般实现
/* WebserviceProxy class */var WebserviceProxy = function() { this.xhrHandler = XhrManager.createXhrHandler();};WebserviceProxy.prototype = {_xhrFailure: function(statusCode) { throw new Error('StatsProxy: Asynchronous request for stats failed.');},_fetchData: function(url, dataCallback, getVars) { var that = this; var callback = {success: function(responseText) { var obj = eval('(' + responseText + ')'); dataCallback(obj); }, failure: that._xhrFailure }; var getVarArray = []; for(varName in getVars) { getVarArray.push(varName + '=' + getVars[varName]); } if(getVarArray.length > 0) { url = url + '?' + getVarArray.join('&'); } xhrHandler.request('GET', url, callback);}};
这个proxy 作为基类,子类实现利用基类的_fetchData方法实现对远程数据的访问、处理
例如:
/* StatsProxy class. */var StatsProxy = function() {}; // implements PageStatsextend(StatsProxy, WebserviceProxy);/* Implement the needed methods. */StatsProxy.prototype.getPageviews = function(callback, startDate, endDate,page) { this._fetchData('/stats/getPageviews/', callback, {'startDate': startDate,'endDate': endDate,'page': page});};StatsProxy.prototype.getUniques = function(callback, startDate, endDate,page) { this._fetchData('/stats/getUniques/', callback, {'startDate': startDate,'endDate': endDate,'page': page});};StatsProxy.prototype.getBrowserShare = function(callback, startDate, endDate,page) { this._fetchData('/stats/getBrowserShare/', callback, {'startDate': startDate,'endDate': endDate,'page': page});};
为 remote proxy 创建了一个通用的基类,我们也为remote proxy 创建一个基类吧
/* DynamicProxy abstract class, incomplete. */var DynamicProxy = function() { this.args = arguments; this.initialized = false;};DynamicProxy.prototype = { _initialize: function() {this.subject = {}; // Instantiate the class.this.class.apply(this.subject, this.args);this.subject.__proto__ = this.class.prototype;var that = this;this.interval = setInterval(function() { that._checkInitialization(); }, 100); }, _checkInitialization: function() {if(this._isInitialized()) {clearInterval(this.interval);this.initialized = true;}}, _isInitialized: function() { // Must be implemented in the subclass. throw new Error('Unsupported operation on an abstract class.'); }};
基类有三个方法,_initialize 用来实例化真实对象的方法;_checkInitialization用来。。。
/* DynamicProxy abstract class, complete. */var DynamicProxy = function() {this.args = arguments;this.initialized = false;if(typeof this.class != 'function') {throw new Error('DynamicProxy: the class attribute must be set before ' +'calling the super-class constructor.');}// Create the methods needed to implement the same interface.for(var key in this.class.prototype) {// Ensure that the property is a function.if(typeof this.class.prototype[key] !== 'function') {continue;}// Add the method.var that = this;(function(methodName) {that[methodName] = function() { if(!that.initialized) { return} return that.subject[methodName].apply(that.subject, arguments);};})(key); }};
- js 设计模式 第十四章 Proxy Pattern
- c#设计模式-proxy pattern
- 设计模式 - Proxy Pattern(代理模式)
- 设计模式[8] Proxy Pattern 代理模式
- 设计模式 - Proxy Pattern(代理模式)
- 设计模式-代理模式(Proxy Pattern)
- 设计模式-代理模式(Proxy Pattern)
- 设计模式-代理模式(Proxy Pattern)
- 设计模式 -- 代理模式(Proxy Pattern)
- 设计模式学习--代理模式(Proxy Pattern)
- 设计模式-代理模式(proxy pattern)
- 设计模式--代理模式【Proxy Pattern】
- 设计模式之---代理模式(Proxy Pattern)
- 设计模式之代理模式(Proxy Pattern)
- java设计模式-代理模式(Proxy Pattern)
- 设计模式之代理模式---Proxy Pattern
- Java设计模式--代理模式【Proxy Pattern】
- 设计模式【代理模式Proxy Pattern】
- 毕业后就是程序员——我的阿里、金山、中华、腾讯、360、网易面试总结
- IT学子成长指导类文章链接(二)
- js
- IT学子成长指导类文章链接(一)
- 【算法设计】矩阵乘法
- js 设计模式 第十四章 Proxy Pattern
- codeforces 238A
- MyEclipse Servlet 模板修改
- HTML文档对象的事件及JS函数解析
- MFC札记
- Windows核心编程——第7章 线程调度
- BMP文件格式详解(BMP file format)
- 什么是网站流量?
- 如何使用gdb调试C程序