網站首頁 編程語言 正文
一、動機(Motivate)
在軟件系統中,采用純粹對象方案的問題在于大量細粒度的對象會很快充斥在系統中,從而帶來很高的運行時代價——主要指內存需求方面的代價。如何在避免大量細粒度對象問題的同時,讓外部客戶程序仍然能夠透明地使用面向對象的方式來進行操作?
二、意圖(Intent)
運用共享技術有效地支持大量細粒度的對象。??????????????????????????????????????? ——《設計模式》GoF
三、結構圖(Structure)
四、模式的組成
(1)、抽象享元角色(Flyweight):此角色是所有的具體享元類的基類,為這些類規定出需要實現的公共接口。那些需要外部狀態的操作可以通過調用方法以參數形式傳入。
(2)、具體享元角色(ConcreteFlyweight):實現抽象享元角色所規定的接口。如果有內部狀態的話,可以在類內部定義。
(3)、享元工廠角色(FlyweightFactory):本角色負責創建和管理享元角色。本角色必須保證享元對象可以被系統適當地共享,當一個客戶端對象調用一個享元對象的時候,享元工廠角色檢查系統中是否已經有一個符合要求的享元對象,如果已經存在,享元工廠角色就提供已存在的享元對象,如果系統中沒有一個符合的享元對象的話,享元工廠角色就應當創建一個合適的享元對象。
(4)、客戶端角色(Client):本角色需要存儲所有享元對象的外部狀態。
五、享元模式的具體代碼實現
/// <summary>
/// 享元的抽象類
/// </summary>
public abstract class Flyweight
{
public abstract void Operation(int extrinsicState);
}
/// <summary>
/// 需要共享的具體類
/// </summary>
public class ConceteFlyweight : Flyweight
{
public override void Operation(int extrinsicState)
{
Console.WriteLine("需要共享的具體Flyweight類:" + extrinsicState);
}
}
/// <summary>
/// 不需要共享的具體類
/// </summary>
public class UnsharedConcreteFlyeight : Flyweight
{
public override void Operation(int extrinsicState)
{
Console.WriteLine("不需要共享的具體Flyweight類:" + extrinsicState);
}
}
/// <summary>
/// 一個工廠類,用來合理創建對象
/// </summary>
public class FlyweightFactory
{
private Dictionary<string, Flyweight> dic = new Dictionary<string, Flyweight>();
public Flyweight GetFlyweight(string key, bool type)
{
if (!dic.ContainsKey(key))
{
Flyweight flyweight = new UnsharedConcreteFlyeight();
if (type)
flyweight = new ConceteFlyweight();
dic.Add(key, flyweight);
}
return (Flyweight)dic[key];
}
}
/// <summary>
/// 客戶端調用
/// </summary>
public class App
{
static void Main()
{
int extrinsicState = 26;
FlyweightFactory factory = new FlyweightFactory();
Flyweight f1 = factory.GetFlyweight("oec2003", true);
f1.Operation(++extrinsicState);
Flyweight f2 = factory.GetFlyweight("oec2003", true);
f2.Operation(++extrinsicState);
Flyweight f3 = factory.GetFlyweight("oec2004", false);
f3.Operation(++extrinsicState);
}
}
六、享元模式的實現要點:
面向對象很好地解決了抽象性的問題,但是作為一個運行在機器中的程序實體,我們需要考慮對象的代價問題。Flyweight設計模式主要解決面向對象的代價問題,一般不觸及面向對象的抽象性問題。
Flyweight采用對象共享的做法來降低系統中對象的個數,從而降低細粒度對象給系統帶來的內存壓力。在具體實現方面,要注意對象狀態的處理。
對象的數量太大從而導致對象內存開銷加大——什么樣的數量才算大?這需要我們仔細的根據具體應用情況進行評估,而不能憑空臆斷。
1、享元模式的優點
(1)、享元模式的優點在于它能夠極大的減少系統中對象的個數。
(2)、享元模式由于使用了外部狀態,外部狀態相對獨立,不會影響到內部狀態,所以享元模式使得享元對象能夠在不同的環境被共享。
2、享元模式的缺點
(1)、由于享元模式需要區分外部狀態和內部狀態,使得應用程序在某種程度上來說更加復雜化了。
(2)、為了使對象可以共享,享元模式需要將享元對象的狀態外部化,而讀取外部狀態使得運行時間變化。
3、在下面所有條件都滿足時,可以考慮使用享元模式:
(1)、一個系統中有大量的對象;
(2)、這些對象耗費大量的內存;
(3)、這些對象中的狀態大部分都可以被外部化;
(4)、這些對象可以按照內部狀態分成很多的組,當把外部對象從對象中剔除時,每一個組都可以僅用一個對象代替軟件系統不依賴這些對象的身份,滿足上面的條件的系統可以使用享元模式。但是使用享元模式需要額外維護一個記錄子系統已有的所有享元的表,而這也需要耗費資源,所以,應當在有足夠多的享元實例可共享時才值得使用享元模式。
七、.NET 中享元模式的實現
.NET在C#中有一個Code Behind機制,它表面有一個aspx文件,背后又有一個cs文件,它的編譯過程實際上會把aspx文件解析成C#文件,然后編譯成dll,在這個過程中,我們在aspx中寫的任何html代碼都會轉化為literal control,literal control是一個一般的文本控件,它就表示html標記。當這些標記有一樣的時候,構建控件樹的時候就會用到Flyweight模式。
它的應用并不是那么平凡,只有在效率空間確實不高的時候我們才用它。
原文鏈接:https://www.cnblogs.com/springsnow/p/11353010.html
相關推薦
- 2023-01-07 MPAndroidChart自定義圖表Chart的Attribute及Render繪制邏輯_Andr
- 2022-11-16 python3中requests庫重定向獲取URL_python
- 2023-02-05 解讀golang中的const常量和iota_Golang
- 2022-10-03 利用正則表達式校驗金額最多保留兩位小數實例代碼_正則表達式
- 2023-11-11 Jetson nano 安裝swapfile 解決Cannot allocate memory 問題
- 2022-04-10 微信小程序 base64 圖片 canvas 畫布 drawImage 實現
- 2022-06-08 利用AOP+Swagger注解實現日志記錄功能
- 2022-05-13 python list.sort()方法排序一探究竟
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支