摘要:作者按每天一個設計模式旨在初步領會設計模式的精髓,目前采用和兩種語言實現。享元模式提醒我們將一個對象的屬性劃分為內部和外部狀態。
作者按:《每天一個設計模式》旨在初步領會設計模式的精髓,目前采用javascript和python兩種語言實現。誠然,每種設計模式都有多種實現方式,但此小冊只記錄最直截了當的實現方式 :)
個人技術博客-godbmw.com 歡迎來玩! 每周至少 1 篇原創技術分享,還有開源教程(webpack、設計模式)、面試刷題(偏前端)、知識整理(每周零碎),歡迎長期關注!本篇博客地址是:《每天一個設計模式之享元模式》。
如果您也想進行知識整理 + 搭建功能完善/設計簡約/快速啟動的個人博客,請直接戳theme-bmw
0. 項目地址享元模式·代碼
《每天一個設計模式》地址
1. 什么是“享元模式”?享元模式:運用共享技術來減少創建對象的數量,從而減少內存占用、提高性能。
享元模式提醒我們將一個對象的屬性劃分為內部和外部狀態。
內部狀態:可以被對象集合共享,通常不會改變
外部狀態:根據應用場景經常改變
享元模式是利用時間換取空間的優化模式。
2. 應用場景享元模式雖然名字聽起來比較高深,但是實際使用非常容易:只要是需要大量創建重復的類的代碼塊,均可以使用享元模式抽離內部/外部狀態,減少重復類的創建。
為了顯示它的強大,下面的代碼是簡單地實現了大家耳熟能詳的“對象池”,以彰顯這種設計模式的魅力。
3. 代碼實現這里利用python和javascript實現了一個“通用對象池”類--ObjectPool。這個類管理一個裝載空閑對象的數組,如果外部需要一個對象,直接從對象池中獲取,而不是通過new操作。
對象池可以大量減少重復創建相同的對象,從而節省了系統內存,提高運行效率。
為了形象說明“享元模式”在“對象池”實現和應用,特別準備了模擬了File類,并且模擬了“文件下載”操作。
通過閱讀下方代碼可以發現:對于File類,內部狀態是pool屬性和download方法;外部狀態是name和src(文件名和文件鏈接)。借助對象池,實現了File類的復用。
注:為了方便演示,Javascript實現的是并發操作,Python實現的是串行操作。輸出結果略有不同。
3.1 Python3 實現from time import sleep class ObjectPool: # 通用對象池 def __init__(self): self.__pool = [] # 創建對象 def create(self, Obj): # 對象池中沒有空閑對象,則創建一個新的對象 # 對象池中有空閑對象,直接取出,無需再次創建 return self.__pool.pop() if len(self.__pool) > 0 else Obj(self) # 對象回收 def recover(self, obj): return self.__pool.append(obj) # 對象池大小 def size(self): return len(self.__pool) class File: # 模擬文件對象 def __init__(self, pool): self.__pool = pool def download(self): # 模擬下載操作 print("+ 從", self.src, "開始下載", self.name) sleep(0.1) print("-", self.name, "下載完成") # 下載完畢后,將對象重新放入對象池 self.__pool.recover(self) if __name__ == "__main__": obj_pool = ObjectPool() file1 = obj_pool.create(File) file1.name = "文件1" file1.src = "https://download1.com" file1.download() file2 = obj_pool.create(File) file2.name = "文件2" file2.src = "https://download2.com" file2.download() file3 = obj_pool.create(File) file3.name = "文件3" file3.src = "https://download3.com" file3.download() print("*" * 20) print("下載了3個文件, 但其實只創建了", obj_pool.size(), "個對象")
輸出結果(這里為了方便演示直接使用了sleep方法,沒有再用多線程模擬):
+ 從 https://download1.com 開始下載 文件1 - 文件1 下載完成 + 從 https://download2.com 開始下載 文件2 - 文件2 下載完成 + 從 https://download3.com 開始下載 文件3 - 文件3 下載完成 ******************** 下載了3個文件, 但其實只創建了 1 個對象3.2 ES6 實現
// 對象池 class ObjectPool { constructor() { this._pool = []; // } // 創建對象 create(Obj) { return this._pool.length === 0 ? new Obj(this) // 對象池中沒有空閑對象,則創建一個新的對象 : this._pool.shift(); // 對象池中有空閑對象,直接取出,無需再次創建 } // 對象回收 recover(obj) { return this._pool.push(obj); } // 對象池大小 size() { return this._pool.length; } } // 模擬文件對象 class File { constructor(pool) { this.pool = pool; } // 模擬下載操作 download() { console.log(`+ 從 ${this.src} 開始下載 ${this.name}`); setTimeout(() => { console.log(`- ${this.name} 下載完畢`); // 下載完畢后, 將對象重新放入對象池 this.pool.recover(this); }, 100); } } /****************** 以下是測試函數 **********************/ let objPool = new ObjectPool(); let file1 = objPool.create(File); file1.name = "文件1"; file1.src = "https://download1.com"; file1.download(); let file2 = objPool.create(File); file2.name = "文件2"; file2.src = "https://download2.com"; file2.download(); setTimeout(() => { let file3 = objPool.create(File); file3.name = "文件3"; file3.src = "https://download3.com"; file3.download(); }, 200); setTimeout( () => console.log( `${"*".repeat(50)} 下載了3個文件,但其實只創建了${objPool.size()}個對象` ), 1000 );
輸出結果如下:
+ 從 https://download1.com 開始下載 文件1 + 從 https://download2.com 開始下載 文件2 - 文件1 下載完畢 - 文件2 下載完畢 + 從 https://download3.com 開始下載 文件3 - 文件3 下載完畢 ************************************************** 下載了3個文件,但其實只創建了2個對象4. 參考
《JavaScript 設計模式和開發實踐》
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/42837.html
摘要:作者按每天一個設計模式旨在初步領會設計模式的精髓,目前采用和兩種語言實現。享元模式提醒我們將一個對象的屬性劃分為內部和外部狀態。 作者按:《每天一個設計模式》旨在初步領會設計模式的精髓,目前采用javascript和python兩種語言實現。誠然,每種設計模式都有多種實現方式,但此小冊只記錄最直截了當的實現方式 :) 個人技術博客-godbmw.com 歡迎來玩! 每周至少 1 篇原創...
摘要:享元模式享元模式是一種優化程序性能的模式本質為減少對象創建的個數。 享元模式 享元模式是一種優化程序性能的模式, 本質為減少對象創建的個數。 以下情況可以使用享元模式:有大量相似的對象, 占用了大量內存對象中大部分狀態可以抽離為外部狀態 demo某商家有 50 種男款內衣和 50 種款女款內衣, 要展示它們 方案一: 造 50 個塑料男模和 50 個塑料女模, 讓他們穿上展示, 代碼如...
摘要:享元模式通過分析應用程序的對象,將其解析為內在數據和外在數據,減少對象數量,從而提高程序的性能。通過這種方式進行事件綁定,可以減少事件處理程序的數量,這種方式叫做事件委托,也是運用了享元模式的原理。事件處理程序是公用的內在部分,每個菜單項各 github 全文地址 : YOU-SHOULD-KNOW-JS JavaScript設計模式之外觀模式 概念 外觀模式:為一組復雜子系統接口提...
閱讀 1120·2021-11-25 09:43
閱讀 1569·2021-10-25 09:47
閱讀 2466·2019-08-30 13:46
閱讀 753·2019-08-29 13:45
閱讀 1280·2019-08-26 13:29
閱讀 2990·2019-08-23 15:30
閱讀 1102·2019-08-23 14:17
閱讀 1325·2019-08-23 13:43