設計模式之---享元模式
阿新 • • 發佈:2021-10-05
享元模式(Flyweight),運用共享技術有效的支援大量細粒度的物件。
什麼時候使用享元模式
如果一個應用程式使用了大量的物件,而大量的這些物件造成了很大的儲存開銷時就可以考慮使用;還有就是物件的大多數狀態可以外部狀態,如果刪除物件的外部狀態,那麼可以用相對較少的共享物件取代很多組物件,此時可以考慮使用享元模式。
歸納享元模式的好處?
用了享元模式,所以有了共享物件,例項總數就打打減少了,如果共享的物件越多,儲存節約的也就越多,節約量隨著共享狀態的增多而增多。
string titlea = "yxz"; string titleb = "yxz"; Console.WriteLine(object.ReferenceEquals(titleb, titlea));
基本程式碼如下:
客戶端程式碼
int extrinsicstate = 22; FlyweightFactory f = new FlyweightFactory(); Flyweight fx = f.GetFlyweight("X"); fx.Operation(--extrinsicstate); Flyweight fyView Code= f.GetFlyweight("Y"); fy.Operation(--extrinsicstate); Flyweight fz = f.GetFlyweight("Z"); fz.Operation(--extrinsicstate); Flyweight uf = new UnsharedConcreteFlyweight(); uf.Operation(--extrinsicstate); Console.Read();
後臺
abstract class Flyweight { public abstract void Operation(int extrinsicsstate); } class ConcreteFlyweight : Flyweight { public override void Operation(int extrinsicsstate) { Console.WriteLine("具體Flyweight:" + extrinsicsstate); } } class UnsharedConcreteFlyweight : Flyweight { public override void Operation(int extrinsicsstate) { Console.WriteLine("不共享的具體Flyweight:" + extrinsicsstate); } } class FlyweightFactory //享元工廠,用來建立並管理Flyweight物件。它主要用來確保合理的共享Flyweight { private Hashtable flyweight = new Hashtable(); public FlyweightFactory() //初始化工廠時,先生成三個例項 { flyweight.Add("X", new ConcreteFlyweight()); flyweight.Add("Y", new ConcreteFlyweight()); flyweight.Add("Z", new ConcreteFlyweight()); } public Flyweight GetFlyweight(string key) //根據客戶端請求,獲得已生成的例項 { return ((Flyweight)flyweight[key]); } }View Code
UML類圖
內部狀態和外部狀態
在享元物件內部並且不會隨環境改變而改變的共享部分,稱為享元物件的內部狀態。隨著環境改變而改變的,不可以共享的狀態就是外部狀態了。
享元模式可以避免大量非常相似類的開銷。
在程式設計中,有時需要生成大量細粒度的類例項來表示資料。如果能發現這些例項除了引數外基本都是相同的,有時就能夠大幅度的減少需要例項化的類的數量。如果能把那些引數轉移到類例項的外面,在方法呼叫時將它們傳遞進來,就可以共享大幅度的減少單個例項的數目。
WebSiteFactory f = new WebSiteFactory(); WebSite fx = f.GetWebsiteCategory("產品展示"); fx.Use(new User("小菜")); WebSite fy = f.GetWebsiteCategory("產品展示"); fx.Use(new User("大鳥")); WebSite fz = f.GetWebsiteCategory("產品展示"); fx.Use(new User("小鳥")); WebSite fr = f.GetWebsiteCategory("產品"); fx.Use(new User("小鳥")); Console.WriteLine("得到網站的分類總數:{0}", f.GetWebSiteCount()); Console.Read();View Code
public class User//使用者類,用於網站的客戶賬號,是網站類的外部狀態 { private string name; public User(string name) { this.name = name; } public string Name { get { return name; } } } abstract class WebSite//網站抽象類 { public abstract void Use(User user); } class ConcreteWebSite:WebSite//具體網站類 { private string name = string.Empty; public ConcreteWebSite(string name) { this.name = name; } public override void Use(User user) { Console.WriteLine("網站分類:" + name + "使用者:" + user.Name); } } class WebSiteFactory { private 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() { return flyweights.Count; } }View Code