基本了解:
享元模式(Flyweight):運用共享技術有效地支援大量細粒度的對象。來提供應用程式的性能,節省系統中重複建立對象執行個體的性能消耗。可以包含以下兩點含義:1、當我們系統中某個對象類型的執行個體較多的情況。2、并且要求這些執行個體進行分類後,發現真正有差別的分類很少的情況。享元模式的基本結構圖。
内部狀态與外部狀态
在享元對象内部并且不會随環境改變而改變的共享部分,可以稱為享元對象的内部狀态,而随環境改變而改變的、不可共享的狀态就是外部狀态。享元模式可以避免大量非常相似類的開銷。享元模式Flyweight執行所需的狀态時有内部的也可能有外部的。内部狀态存儲于ConcreteFlyweight對象中,而外部對象則應該考慮有用戶端對象存儲或計算,當調用Flyweight對象的操作時,将該狀态傳遞給他。結合網站開發的例子。
//使用者,用于網站的客戶賬号,是網站類的外部狀态
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 = "";
public ConcreteWebSite(string name)
{
this.name = name;
}
public override void Use(User user) //實作use方法
{
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;
}
}
用戶端代碼:
static void Main(string[] args)
{
WebSiteFactory f = new WebSiteFactory();
WebSite fx = f.GetWebSiteCategory("産品展示"); //執行個體化“産品展示”的“網站”對象
fx.Use(new User("小菜"));
WebSite fy = f.GetWebSiteCategory("産品展示"); //共享上方生成的對象,不再執行個體化
fy.Use(new User("大鳥"));
WebSite fz = f.GetWebSiteCategory("産品展示");
fz.Use(new User("嬌嬌"));
WebSite f1 = f.GetWebSiteCategory("部落格");
f1.Use(new User("老頑童"));
WebSite f2 = f.GetWebSiteCategory("部落格");
f2.Use(new User("桃谷六仙"));
WebSite f3 = f.GetWebSiteCategory("部落格");
f3.Use(new User("南海鳄神"));
Console.WriteLine("得到網站分類總數為{0}", f.GetWebSiteCount()); //統計執行個體化個數,結果輸出顯示
Console.Read();
}
享元模式應用
1、應用程式使用了大量的對象,而大量的這些對象造成了很大的存儲開銷是考慮使用。 2、對象的大多數狀态為外部狀态,删除這些狀态可以用相對較少的共享對象取代。
因為用了享元模式,有了共享的對象,執行個體總數就大大減少了,如果共享的對象越多,存儲節約就越多,節約量随着共享狀态的增多而增大。