大話設計模式-享元模式
阿新 • • 發佈:2018-12-06
享元模式
運營共享技術有效地支援大量細粒度的物件。
享元模式的原理
享元模式可以避免大量非常相似類的開銷。在程式設計中,有時需要生成大量細粒度的類的例項來表示資料。
如果能發現這些例項除了幾個引數外基本都是相通的,有時就能夠大幅地減少需要例項化的類的數量。
如果能把那些引數移到類的例項的外面,在方法呼叫時將他們傳遞進來,就可以通過共享大幅地減少單個例項的數目。
我的理解是原來一個物件的例項,它的欄位和屬性佔用100KB,那麼100個物件就是佔用了100*100KB記憶體,現在把不變的提煉出來共享,比如欄位和屬性中由50KB是不變的,那100個物件就是佔用了100*50KB(變的)+50KB(不變的)的記憶體。
佔用記憶體=外部資訊大小*外部資訊例項數量+內部資訊大小*內部資訊例項數量
維護一個鍵值對,外部資訊的某個欄位作為鍵,內部資訊例項作為值,這樣就做到了共享內部資訊。
享元模式的使用時機
如果一個應用程式使用了大量的物件,而大量的物件造成了很大的儲存開銷。
物件的大多數狀態是外部狀態,如果刪除物件的外部狀態,那麼可以用相對較少的共享物件取代很多組物件。
享元模式結構演示
使用者
public class User { public string Name { get; private set; } public User(string name) => Name = name; }
網站抽象
abstract class WebSite { public abstract void Use(User user); }
具體網站
class ConcreteWebsite : WebSite { private string name = ""; public ConcreteWebsite(String name) => this.name = name; public override void Use(User user) => Console.WriteLine($"網站分類:{name} 使用者:{user.Name}"); }
網站工廠
class WebSiteFactory { Hashtable flyweights = new Hashtable(); public WebSite GetWebSiteCategory(string key) { if (!flyweights.ContainsKey(key)) flyweights.Add(key,new ConcreteWebsite(key)); return ((WebSite)flyweights[key]); } public int GetWebsiteCount() => flyweights.Count; }
測試結果
//網站工廠 WebSiteFactory f = new WebSiteFactory(); //宣告兩個論壇 WebSite fx = f.GetWebSiteCategory("論壇"); fx.Use(new User("路人甲")); WebSite fy = f.GetWebSiteCategory("論壇"); fy.Use(new User("路人乙")); //宣告兩個部落格 WebSite fi = f.GetWebSiteCategory("部落格"); fi.Use(new User("路人A")); WebSite fj = f.GetWebSiteCategory("部落格"); fj.Use(new User("路人B")); //列印網站種類數量 Console.WriteLine($"網站的種類數量為:{f.GetWebsiteCount()}"); //測試結果 網站分類:論壇 使用者:路人甲 網站分類:論壇 使用者:路人乙 網站分類:部落格 使用者:路人A 網站分類:部落格 使用者:路人B 網站的種類數量為:2