2.5.1 模式意圖:
在系統中會有一些反復使用的元素,這些元素一般使用周期較短,但使用頻率高,為了達到提高復用性和節省內存的目的,則可以使用享元模式。
2.5.2 模式概念:
它屬于結構型模式,運用共享技術有效地支持大量細粒度的對象。類似于游戲開發中的對象池。
2.5.3 模式元素:
- 享元類抽象(Flyweight)
- 享元類細節(ConcreteFlyweight)
- 非共享享元類細節(UnsharedConcreteFlyweight)
- 享元工廠類(FlyweightFactory)
2.5.4 代碼示例:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Custom.Log;
public class FlyweightFactory
{
private Hashtable flyweights = new Hashtable();
public FlyweightFactory()
{
flyweights.Add("X", new ConcreteFlyweight());
flyweights.Add("Y", new ConcreteFlyweight());
flyweights.Add("Z", new ConcreteFlyweight());
}
public Flyweight GetFlyweight(string key)
{
return ((Flyweight)flyweights[key]);
}
}
public abstract class Flyweight
{
public abstract void Operation(int extrinsicstate);
}
public class ConcreteFlyweight : Flyweight
{
public override void Operation(int extrinsicstate)
{
this.Log("具體Flyweight:" + extrinsicstate);
}
}
public class UnsharedConcreteFlyweight : Flyweight
{
public override void Operation(int extrinsicstate)
{
this.Log("不共享的具體Flyweight:" + extrinsicstate);
}
}
示例調用
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FlyweightComponent : MonoBehaviour
{
public void Start()
{
int extrinsicState = 22;
FlyweightFactory f = new FlyweightFactory();
Flyweight fx = f.GetFlyweight("X");
fx.Operation(--extrinsicState);
Flyweight fy = f.GetFlyweight("Y");
fy.Operation(--extrinsicState);
Flyweight fz = f.GetFlyweight("Z");
fz.Operation(--extrinsicState);
UnsharedConcreteFlyweight uf = new UnsharedConcreteFlyweight();
uf.Operation(--extrinsicState);
}
}
2.5.5 寫法對比:
略
2.5.6 模式分析:
此模式是通過共享技術,來提高相同或相似對象的利用率,有效減少因頻繁實例或銷毀造成的性能開銷,并且減少內存壓力。
- 優點:大大減少對象的創建,降低系統內存占用,對象使用率提高。
- 缺點:提高了系統的復雜度,需要分離出外部狀態(根據上下文傳入的參數)和內部狀態(通用部分),而且外部狀態相對獨立,不應該隨著內部狀態的變化而變化,否則會造成系統的混亂。
【額外說明】:
對于HashMap中所持有的享元元素,為了更精確的控制還要注意控制其元素的生命周期,以規定檢查的方式清除不必要的元素,進一步緩解內存壓力。
如何檢查:主動觸發式檢查、 被動觸發檢查、系統定期檢查。
按何權重清理:元素的剩余時間、元素使用次數、自定義權重算法。
2.5.7 應用場景:
如果遇到下面這些情況,可以考略使用享元模式
- 系統中有大量對象或對象較消耗內存
- 系統不依賴于這些對象的身份(例如唯一標識),這些對象是不可分辨的。
2.5.8 小結:
對于使用享元模式帶來性能提高的同時,也要關注其對系統復雜性的影響。在性能的提高和共享粒度控制之間尋找有效的平衡點。