[英]What is the difference between intrinsic and extrinsic state as described in Flyweight Pattern?
從本章FlyWeight
內側的圖案四人幫Flyweight模式適用於當大多數對象狀態可以制成外在的。
extrinsic state
是什么意思? 我覺得這種模式用於共享對象。 如果要共享對象,那么該對象怎么可能有任何狀態呢?
讓我們以文字處理器為例:
文字處理器處理 Character 對象。 Character 對象的狀態是字符內容、字體、樣式、位置等(就字處理器而言)。 不同的文檔使用不同的字符實例。 假設我們只是處理az字符,不同的文檔使用az池中的字母,但可能會應用不同的字體/樣式。 因此,如果我們將字符的內容與字體/樣式分開,我們可以共享這些字符,這是有道理的,因為與使用的不同字符實例相比,不同類型的字符總數更少(在我們的例子中為 26,否則為常數)在不同的文件中。 共享這些字符實例意味着明智地共享 Character 實例的內容並將諸如字體/樣式之類的上下文應用於這些字符的外部。 字符內容是內在狀態,字體/樣式是外在狀態。 在上面的例子中,將狀態分為內在和外在狀態導致了巨大的存儲節省。
外部 - 屬於對象上下文(外部)或該實例唯一的狀態
固有 - 自然屬於“FlyWeight”對象的狀態,因此應該是永久的或不可變的(內部)或上下文無關的。
無論該項目符號列表中的具體措辭是什么,理解以下信息很重要:享元適用於狀態的重要部分可以在許多對象之間共享的情況,因為它是所有對象相同的一些數據。 通常,共享狀態本質上是不可變的(即“普遍真理”)。 帶有字體的示例使這一點非常清楚; 來自日常 Java 的一個例子是java.util.regex.Pattern
,flyweight 與Matcher
,客戶端對象重用它並保存本地外部狀態。 許多Matcher
可以並行存在,都在內部重用已編譯的正則表達式。
這句話比你問題中的那句話更清楚:
共享的享元越多,節省的存儲空間就越大。 節省隨着共享狀態的數量而增加。 當對象同時使用大量的內在和外在狀態,並且外在狀態可以被計算而不是存儲時,節省的最多。 然后您可以通過兩種方式節省存儲空間:共享降低了內在狀態的成本,並且您可以用外在狀態換取計算時間。
Gang of Four 的Flyweight 設計模式引入了內在和外在狀態的概念:
這里的關鍵概念是內在狀態和外在狀態之間的區別。 固有狀態存儲在享元中; 它由獨立於享元上下文的信息組成,從而使其可共享。 外部狀態取決於享元的上下文並隨享元的上下文而變化,因此無法共享。 客戶端對象負責在需要時將外部狀態傳遞給享元。
換句話說,對象的狀態可以相對於一組對象分解為內在狀態和外在狀態,其中內在狀態是該組中所有對象的狀態的交集,外在狀態是物體狀態與內在狀態的區別。 由於固有狀態在組的每個對象中重復,因此可以通過用存儲單個固有狀態的單個享元對象替換對象組來節省空間。 然而,享元對象無法存儲組中對象的多個外部狀態,因此外部狀態存儲在外部,並在來自客戶端對象的每個請求中傳遞給享元對象。 這種優化的通信協議通常被稱為無狀態協議,因為享元對象不存儲外部狀態。 無狀態協議的示例包括 IP 和 HTTP(以及更一般的任何 REST 協議,其中內在狀態稱為資源狀態,外在狀態稱為應用程序狀態)。
例如,讓我們將三個對象與它們各自的客戶端:
o1 ← c1
o2 ← c2
o3 ← c3
我們可以將每個對象的狀態分解為三個對象:
狀態 1 =內在狀態∪外在狀態 1
狀態 2 =內在狀態∪外在狀態 2
狀態 3 =內在狀態∪外在狀態 3在哪里:
內在狀態=狀態 1 ∩狀態 2 ∩狀態 3
外在狀態 1 =狀態 1 \\內在狀態
外在狀態 2 =狀態 2 \\內在狀態
外在狀態 3 =狀態 3 \\內在狀態
這里復制了固有狀態。 因此,將其存儲在單個享元對象中(並將外部狀態移動到客戶端)可以節省空間:
○ ← c1, c2, c3
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.