Open qiuhongbingo opened 4 years ago
/** * 享元模式是用于性能优化的一种常见模式,它依靠: * 减少创建对象实例的数量 * 运用共享技术来有效支持大量细粒度的对象 * 这两种方式减少内存占用,以提高性能 */ /** * 例子:在图书管理系统中,每本书都有以下特性: * ID * Title * Author * Genre * Page count * Publisher ID * ISBN */ /** * 同时我们需要以下属性来追踪每一本书时,记录它是否可用、归还时间等: * checkoutDate * checkoutMember * dueReturnDate * availability */ // 那么 Book 类看上去像 var Book = function(id, title, author, genre, pageCount, publisherID, ISBN, checkoutDate, checkoutMember, dueReturnDate, availability) { this.id = id this.title = title this.author = author this.genre = genre this.pageCount = pageCount this.publisherID = publisherID this.ISBN = ISBN this.checkoutDate = checkoutDate this.checkoutMember = checkoutMember this.dueReturnDate = dueReturnDate this.availability = availability } Book.prototype = { getTitle: function() { return this.title }, getAuthor: function() { return this.author }, getISBN: function() { return this.ISBN }, updateCheckoutStatus: function(bookID, newStatus, checkoutDate, checkoutMember, newReturnDate) { this.id = bookID this.availability = newStatus this.checkoutDate = checkoutDate this.checkoutMember = checkoutMember this.dueReturnDate = newReturnDate }, extendCheckoutPeriod: function(bookID, newReturnDate) { this.id = bookID this.dueReturnDate = newReturnDate }, isPastDue: function() { var currentDate = new Date() return currentDate.getTime() > Date.parse(this.dueReturnDate) } } /** * 这么看上去并没有什么问题,但是当图书增多时,对于系统的压力会逐渐增多 * 为此我们将书的属性分为两种:本身固有的和外在特性 */ // 我们简化书的构造函数为 var Book = function(title, author, genre, pageCount, publisherID, ISBN) { this.title = title this.author = author this.genre = genre this.pageCount = pageCount this.publisherID = publisherID this.ISBN = ISBN } /** * 我们将外在特性删去,check-outs 等信息将会被移动到一个新的类中,一个新的工厂函数也将出现 * 在这个工厂函数中,我们将会检查当前需要创建的书籍是否已经存在,如果存在直接返回书实例 * 否则进行调用 Book 构造函数进行创建 * 这保证了所有的书都是唯一的,而不存在重复 */ var BookFactory = (function() { var existingBooks = {} var existingBook return { createBook: function(title, author, genre, pageCount, publisherID, ISBN) { existingBook = existingBooks[ISBN] if (!!existingBook) { return existingBook } else { var book = new Book(title, author, genre, pageCount, publisherID, ISBN) existingBooks[ISBN] = book return book } } } })() /** * 书目所有的外在特性都被从书本身的特性中抽离 * 现在被移动到 BookManager 的 BookDatabase 当中 * 对于书借入/借出的操作也移动到了 BookRecordManager 当中,因为这些方法需要直接操作书的外在特性 * 如此一来,比一本书拥有多项属性的大 object 模式更加高效,也更利于维护 * 如果有 30 本同样一本书的 copy,现有的模式下只存储了一个实例 * 同时对于书状态转移的函数,我们维护在 BookManager 当中,而不再出现在对象(原型)上 * 如果这些函数出现在每一个书实例当中,将会是更大的开销 */ var BookRecordManager = (function() { var bookRecordDatabase = {} return { addBookRecord: function(id, title, author, genre, pageCount, publisherID, ISBN, checkoutDate, checkoutMember, dueReturnDate, availability) { var book = BookFactory.createBook(title, author, genre, pageCount, publisherID, ISBN) bookRecordDatabase[id] = { checkoutMember: checkoutMember, checkoutDate: checkoutDate, dueReturnDate: dueReturnDate, availability: availability, book: book } }, updateCheckoutStatus: function(bookID, newStatus, checkoutDate, checkoutMember, newReturnDate) { var record = bookRecordDatabase[bookID] record.availability = newStatus record.checkoutDate = checkoutDate record.checkoutMember = checkoutMember record.dueReturnDate = newReturnDate }, extendCheckoutPeriod: function(bookID, newReturnDate) { bookRecordDatabase[bookID].dueReturnDate = newReturnDate }, isPastDue: function(bookID) { var currentDate = new Date() return currentDate.getTime() > Date.parse(bookRecordDatabase[bookID].dueReturnDate) } } })() /** * 享元模式在前端还有更多的应用,比如事件代理就是一个很典型的体现 */ { /* <div id="container"> <div class="toggle" href="#"> <span class="info">1</span> </div> <div class="toggle" href="#"> <span class="info">2</span> </div> </div> */ } // 我们集中将事件处理放到父容器上 var stateManager = { fly: function() { var self = this $('#container') .unbind() .on('click', 'div.toggle', function(e) { self.handleClick(e.target) }) }, handleClick: function(elem) { $(elem) .find('span') .toggle('slow') } }