㈠ 享元模式的使用場景
如果一個應用程序使用了大量的對象,而這些對象造成了很大的存儲開銷的時候就可以考慮是否可以使用享元模式。
例如,如果發現某個對象的生成了大量細粒度的實例,並且這些實例除了幾個參數外基本是相同的,如果把那些共享參數移到類外面,在方法調用時將他們傳遞進來,就可以通過共享大幅度單個實例的數目。
㈡ 23種設計模式--享元模式
運用共享技術來有效地支持大量細粒度對象的復用。它通過共享已經存在的對象來大幅度減少需要創建的對象數量、避免大量相似對象的開銷,從而提高系統資源的利用率。
享元模式中存在以下兩種狀態:
1、內部狀態,即不會隨著環境的改變而改變的可共享部分。
2、外部狀態,指隨環境改變而改變的不可以共享的部分。享元模式的實現要領就是區分應用中的這兩種狀態,並將外部狀態外部化。
抽象享元角色
具體享元角色
享元工廠角色
測試類
㈢ 請簡述什麼是享元模型,並舉例說明它在ios開發中的一處運用
在面向對象軟體設計中,利用公共對象不僅能節省資源還能提高性能。共享的對象只能提供某些內在的信息,而不能用來識別對象。專門用於設計可共享對象的一種設計模式叫做享元模式(Flyweight pattern)。
實現享元模式需要兩個關鍵組件,通常是可共享的享元對象和保存他們的池。某種中央對象維護這個池,並從它返回適當的實例。
運用共享技術有效地支持大量細粒度的對象。
何時使用:
(1)應用程序使用很多對象;
(2)在內存中保存對象會影響內存性能;
(3)對象的多數特有狀態(外在狀態)可以放到外部而輕量化;
(3)移除了外在狀態後,可以用較少的共享對象替代原來的那組對象;
(4)應用程序不依賴於對象標示,因為共享對象不能提供唯一的標示。
㈣ 23、Android設計模式---(對象共享、避免創建多對象)享元模式
又稱 FlyWeight,代表輕量級的意思,結構型設計模式。
享元模式是對象池的一種實現。類似於線程池,線程池可以避免不停的創建和銷毀多個對象,消耗性能。享元模式也是為了減少內存的使用,避免出現大量重復的創建銷毀對象的場景。
享元模式用在一批相同或相似的對象上,這些對象有可以共享的內部狀態和各自不同的外部狀態。
享元模式中會有一個工廠,工廠維護著一個容器,容器以鍵值對的方式存儲,鍵是對象的內部狀態,也就是共享的部分,值就是對象本身。客戶端從這個工廠獲取對象,如果容器中存在這個對象就直接返回,不存在再創建新的對象並存入容器,避免了大量重復創建對象。
使用共享對象有效的支持大量的細粒度對象的復用。
系統中存在大量的 相似對象。
細粒度的對象都具備較接近的外部狀態,且內部狀態與環境無關,即對象沒有特定身份。
需要 緩沖池 的場景。
例1. 過年回家買火車票,無數人在客戶端上訂票 (有多次購票、刷票的情況),即不斷向服務端發送請求。
而每次查詢,伺服器必須做出回應,具體地,用戶查詢輸入出發地和目的地,查詢結構返回值只有一趟列車的車票。而數以萬計的人有同樣需求,即不間斷請求數據,每次重新創建一個查詢的車票結果,即造成大量重復對象創建、銷毀,使得伺服器壓力加重。
享元模式正好適合解決該情形的問題,例如 A 到 B 地的車輛是有限的,車上鋪位分硬卧、軟卧和坐票三種,將這些可公用的對象緩存起來。用戶查詢時優先使用緩存,反之則重新創建。
我們知道 Java 中 String 是存在於常量池中,即一個 String 被定義之後它就被緩存到了常量池中,當其他地方使用同樣的字元串,則直接使用緩存,而非創建。
享元模式的優缺點
優點 - 大幅度地降低內存中對象的數量。
缺點-1) 為了使對象可共享,需將一些狀態外部化,使程序的邏輯復雜化
㈤ 什麼是享元模式
享元模式主要是為了解決大量對象創建後,增大了系統的資源開銷,為了解決此問題,該模式通過共享對象的方式實現。
接下來,以一個實際例子來簡單介紹下享元模式,假設有這么一個場景有兩個用戶服務類,分別是普通用戶服務與VIP用戶服務,其中有個Operation操作,而該操作主要是為了完成用戶注冊過程,在注冊過程中,需要通過調用簡訊介面來完成注冊流程;這時兩個用戶服務都需要一個HTTP連接池來完成此功能;如果每個類都單獨創建一個HTTP連接池,那麼系統將會產生兩份資源開銷,而其利用率將會很低;
為此,通過如下圖例中的設計方式,將HTTP連接池的在用戶服務工廠中進行創建,通過抽象工廠模式建立多種不同的用戶服務子類實現,並將HTTP連接池在子類實例間進行共享,實現降低資源開銷,提升連接池的資源利用率。
㈥ 享元模式的示例
典型的享元模式的例子為文書處理器中以圖形結構來表示字元。一個做法是,每個字形有其字型外觀, 字模 metrics, 和其它格式資訊,但這會使每個字元就耗用上千位元組。取而代之的是,每個字元參照到一個共享字形物件,此物件會被其它有共同特質的字元所分享;只有每個字元(文件中或頁面中)的位置才需要另外儲存。以下程式用來解釋上述的文件例子。這個例子用來解釋享元模式利用只載立執行立即小任務所必需的資料,因而減少內存使用量。
public enum FontEffect {
BOLD, ITALIC, SUPERSCRIPT, SUBSCRIPT, STRIKETHROUGH
}
public final class FontData {
/**
* A weak hash map will drop unused references to FontData.
* Values have to be wrapped in WeakReferences,
* because value objects in weak hash map are held by strong references. *
/
private static final WeakHashMap<FontData, WeakReference<FontData>> FLY_WEIGHT_DATA = new WeakHashMap<FontData, WeakReference<FontData>>();
private final int pointSize;
private final String fontFace;
private final Color color;
private final Set<FontEffect> effects;
private FontData(int pointSize, String fontFace, Color color, EnumSet<FontEffect> effects){ this.pointSize = pointSize;
this.fontFace = fontFace;
this.color = color;
this.effects = Collections.unmodifiableSet(effects);
}
public static FontData create(int pointSize, String fontFace, Color color, FontEffect... effects) { EnumSet<FontEffect> effectsSet = EnumSet.noneOf(FontEffect.class);
for (FontEffect fontEffect : effects) {
effectsSet.add(fontEffect);
}
// We are unconcerned with object creation cost, we are recing overall memory consumption FontData data = new FontData(pointSize, fontFace, color, effectsSet);
// Retrieve previously created instance with the given values if it (still) exists WeakReference<FontData> ref = FLY_WEIGHT_DATA.get(data);
FontData result = (ref != null) ? ref.get() : null; // Store new font data instance if no matching instance exists
if (result == null) {
FLY_WEIGHT_DATA.put(data, new WeakReference<FontData> (data));
result = data;
}
// return the single immutable with the given values
return result;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof FontData) {
if (obj == this) {
return true;
}
FontData other = (FontData) obj;
return other.pointSize == pointSize && other.fontFace.equals(fontFace) && other.color.equals(color) && other.effects.equals(effects);
}
return false;
}
@Override
public int hashCode() {
return (pointSize * 37 + effects.hashCode() * 13) * fontFace.hashCode();
}
// Getters for the font data, but no setters. FontData is immutable.
}
㈦ 享元模式
面向對象技術可以很好地解決一些靈活性或可擴展性問題,但在很多情況下需要在系統中增加類和對象的個數。當對象數量太多時,將導致運行代價過高,帶來性能下降等問題。
享元模式(Flyweight Pattern):運用共享技術有效地支持大量細粒度對象的復用。系統只使用少量的對象,而這些對象都很相似,狀態變化很小,可以實現對象的多次復用。由於享元模式要求能夠共享的對象必須是細粒度對象,因此它又稱為輕量級模式,它是一種對象結構型模式。
享元模式包含如下角色:
運行結果:
享元模式是一個考慮系統性能的設計模式,通過使用享元模式可以節約內存空間,提高系統的性能。
享元模式的核心在於享元工廠類,享元工廠類的作用在於提供一個用於存儲享元對象的享元池,用戶需要對象時,首先從享元池中獲取,如果享元池中不存在,則創建一個新的享元對象返回給用戶,並在享元池中保存該新增對象。
享元模式以共享的方式高效地支持大量的細粒度對象,享元對象能做到共享的關鍵是區分內部狀態(Internal State)和外部狀態(External State)。
享元模式的優點
享元模式的缺點
在以下情況下可以使用享元模式:
享元模式在編輯器軟體中大量使用,如在一個文檔中多次出現相同的圖片,則只需要創建一個圖片對象,通過在應用程序中設置該圖片出現的位置,可以實現該圖片在不同地方多次重復顯示。
單純享元模式和復合享元模式
享元模式與其他模式的聯用
摘自: https://www.doudianyun.com/2020/06/%E7%BB%93%E6%9E%84%E5%9E%8Bc-5-%E4%BA%AB%E5%85%83%E6%A8%A1%E5%BC%8F/