代理模式
1.本体
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']); /* PublicLibrary class. */ var PublicLibrary = function(books) { // implements Library this.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) { var results = []; for(var isbn in this.catalog) { if(!this.catalog.hasOwnProperty(isbn)) continue; if(searchString.match(this.catalog[isbn].getTitle()) || searchString.match(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('PublicLibrary: book ' + book.getTitle() + ' is not currently available.'); } } else { throw new Error('PublicLibrary: book ' + book.getTitle() + ' not found.'); } }, returnBook: function(book) { var isbn = book.getIsbn(); if(this.catalog[isbn]) { this.catalog[isbn].available = true; } else { throw new Error('PublicLibrary: book ' + book.getTitle() + ' not found.'); } } };
2.实例代理
/* 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); } };
3.虚拟代理
/* 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); } };
4.远程模式
/* 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); } }; /* StatsProxy class, using WebserviceProxy. */ var StatsProxy = function() {}; // implements PageStats extend(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 }); }; StatsProxy.prototype.getTopSearchTerms = function(callback, startDate, endDate, page) { this._fetchData('/stats/getTopSearchTerms/', callback, { 'startDate': startDate, 'endDate': endDate, 'page': page }); }; StatsProxy.prototype.getMostVisitedPages = function(callback, startDate, endDate) { this._fetchData('/stats/getMostVisitedPages/', callback, { 'startDate': startDate, 'endDate': endDate }); };