Rust語言之GoF設計模式:Flyweight享元模式

banq 發表於 2022-09-26
設計模式 Go

Flyweight(快取/享元)是一種結構設計模式,它允許程式透過保持低消耗來支援大量的物件。
它可以是一個隱藏在類似 Facade 的 API 後面的內部快取。快取儲存從多個物件引用的共享部分。

Flyweight是讓weight重量的東西飛起來,實現輕量化,當你有需要更輕量級的物件時發揮作用,通常是因為你有太多的物件。

遊戲中廣袤的樹林場景是如何實現的?
霧氣散去,露出一片雄偉的古老森林。古老的鐵杉,數不勝數,聳立在你面前,形成一個綠色的大教堂。樹葉的彩色玻璃罩將陽光分割成金色的霧狀。在巨大的樹幹之間,你可以看到巨大的森林正在向遠處退去。

當你在螢幕上填滿了一整片單獨的樹木時,圖形程式設計師所看到的只是數百萬個多邊形,他們必須以某種方式每六十分之一秒將其渲染到 GPU 上。
每棵樹都有包含數千個多邊形的詳細幾何圖形。即使您有足夠的記憶體來描述該森林,為了渲染它,該資料也必須透過匯流排從 CPU 傳輸到 GPU。
使用Direct3D 和 OpenGL 的例項渲染,它們佔用的記憶體不是太多,而是它們需要太多時間將每個單獨的樹透過匯流排推送到 GPU。

輕量化享元模式是透過將物件的資料分成兩種來解決這個問題。
  • 第一種資料是不特定於該物件的單個例項並且可以在所有例項之間共享的東西。GoF四人組稱這是內在狀態,但也可視為“無上下文”的東西。如樹的幾何形狀和紋理。
  • 其餘資料是外部狀態,即某個例項獨有的東西,無法在多個例項之間共享的。如每棵樹的位置、比例和顏色。

這種模式透過在物件出現的每個地方共享一個內在狀態複製副本來節省記憶體。

如果一個事物或物件沒有明確定義的標識的情況下可以成為共享物件,在這些情況下,感覺更像是一個物體神奇地同時出現在多個地方。
DDD值物件 概念也是這種享元模式的實現。

這個模式類似於型別物件Type Object
享元和型別物件之間的界限有點​​棘手。使用型別物件來使事情更容易維護,並且避免必須為東西建立實際的類。共享記憶體是一個不錯的獎勵。使用flyweights唯一的目的是資源共享。