設計模式之享元模式

来源:http://www.cnblogs.com/snaildev/archive/2017/10/12/7655465.html
-Advertisement-
Play Games

什麼是享元模式? 所謂享元模式就是運行共用技術有效地支持大量細粒度對象的復用。系統使用少量對象,而且這些都比較相似,狀態變化小,可以實現對象的多次復用。共用模式是支持大量細粒度對象的復用,所以享元模式要求能夠共用的對象必須是細粒度對象。兩個重要的概念:內部狀態、外部狀態。 內部狀態:在享元對象內部不 ...


什麼是享元模式?

所謂享元模式就是運行共用技術有效地支持大量細粒度對象的復用。系統使用少量對象,而且這些都比較相似,狀態變化小,可以實現對象的多次復用。共用模式是支持大量細粒度對象的復用,所以享元模式要求能夠共用的對象必須是細粒度對象。
兩個重要的概念:內部狀態、外部狀態。

  • 內部狀態:在享元對象內部不隨外界環境改變而改變的共用部分。
  • 外部狀態:隨著環境的改變而改變,不能夠共用的狀態就是外部狀態。

正因為享元模式區分了內部狀態和外部狀態,我們就可以通過設置不同的外部狀態使得相同的對象可以具備一些不同的特性,而內部狀態設置為相同部分。在我們的程式設計過程中,我們可能會需要大量的細粒度對象來表示對象,如果這些對象除了幾個參數不同外其他部分都相同,這個時候我們就可以利用享元模式來大大減少應用程式當中的對象。如何利用享元模式呢?這裡我們只需要將他們少部分的不同的部分當做參數移動到類實例的外部去,然後再方法調用的時候將他們傳遞過來就可以了

具體代碼實現

/// <summary>
/// 抽象享元類
/// </summary>
public abstract class Flyweight
{
    public abstract void Operation(int extrinsicstate);
}

/// <summary>
/// 具體享元對象
/// </summary>
public class ConcreteFlyweight : Flyweight
{
    /// <summary>
    /// 內部狀態
    /// </summary>
    private string intrinsicstate;

    /// <summary>
    /// 構造函數
    /// </summary>
    /// <param name="innerState"></param>
    public ConcreteFlyweight(string innerState)
    {
        this.intrinsicstate = innerState;
    }

    /// <summary>
    /// 操作
    /// </summary>
    /// <param name="extrinsicaste">外部狀態</param>
    public override void Operation(int extrinsicstate)
    {
        Console.WriteLine($"具體實現類: intrinsicstate {intrinsicstate}, extrinsicstate {extrinsicstate}");
    }
}

/// <summary>
/// 享元工廠,負責創建和管理享元對象
/// </summary>
public class FlyweightFactory
{
    /// <summary>
    /// 享元對象記憶體緩存
    /// </summary>
    public Dictionary<string, Flyweight> flyweights = new Dictionary<string, Flyweight>();

    public FlyweightFactory()
    {
        flyweights.Add("A", new ConcreteFlyweight("A"));
        flyweights.Add("B", new ConcreteFlyweight("B"));
        flyweights.Add("C", new ConcreteFlyweight("C"));
    }

    public Flyweight GetFlyweight(string key)
    {
        if (!flyweights.ContainsKey(key))
        {
            Console.WriteLine($"駐留池中不存在字元串{key}");

            flyweights.Add(key, new ConcreteFlyweight(key));
        }

        return flyweights[key] as Flyweight;
    }
}

/// <summary>
/// 客戶端調用
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
    int externalstate = 10; // 定義外部狀態,如字母的位置等信息
    FlyweightFactory factory = new FlyweightFactory(); // 初始化享元工廠

    Flyweight fa = factory.GetFlyweight("A");
    fa.Operation(--externalstate);

    Flyweight fb = factory.GetFlyweight("B");
    fb.Operation(--externalstate);

    Flyweight fd = factory.GetFlyweight("D");
    fd.Operation(--externalstate);

    Console.ReadLine();
}

輸出

具體實現類: intrinsicstate A, extrinsicstate 9
具體實現類: intrinsicstate B, extrinsicstate 8
駐留池中不存在字元串D
具體實現類: intrinsicstate D, extrinsicstate 7

享元模式的優缺點

優點: 降低了系統中對象的數量,從而降低了系統中細粒度對象給記憶體帶來的壓力。
缺點: 為了使對象可以共用,需要將一些狀態外部化,這使得程式的邏輯更複雜,使系統複雜化。

享元模式的應用場景

在下麵所有條件都滿足時,可以考慮使用享元模式:

  • 一個系統中有大量的對象;
  • 這些對象耗費大量的記憶體;
  • 這些對象中的狀態大部分都可以被外部化
  • 這些對象可以按照內部狀態分成很多的組,當把外部對象從對象中剔除時,每一個組都可以僅用一個對象代替
  • 軟體系統不依賴這些對象的身份,

.NET中,String類的實現用到了享元模式,可以參考字元串駐留池的相關介紹。

代碼


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 今天在一段程式中看到這樣一個很奇怪的語句: 博主查了之後發現業界稱其萬能頭文件,這個頭文件包含瞭如下等頭文件,幾乎包含了所有的C++標準庫頭文件,使用後代碼中省去了相當多的頭文件的書寫 但也有以下兩個缺點: 1、因其包含的頭文件的過多,導致程式編譯慢 2、其不屬於標準庫裡面的頭文件,只是gcc的內部 ...
  • 閑來沒事,想整理下一些知識。 這篇文章是關於spring的web程式的搭建,有什麼不對的地方希望大家批評指正。 首先我們要瞭解什麼是spring,這裡可能很多大家也都明白,無非是一個管理對象的一個容器,主要體現在IOC註入和AOP切麵編程。 關於上面的兩點在後面一點會給大家更具體的說明一下是什麼。 ...
  • 視頻直播是指利用互聯網及流媒體技術進行直播,視頻因融合了圖像、文字、聲音等豐富元素,聲形並茂,效果極佳,逐漸成為互聯網的主流表達方式。初期相關參考:HTTP 長連接和短連接灰度發佈A/B測試今天先到這兒,希望對您在系統架構設計與評估,團隊管理, 項目管理, 產品管理,團隊建設 有參考作用 , 您可能... ...
  • 十一宅了,也沒學習看啥書,所有時間花在了圍棋上,雖然很頹廢,不過令人欣慰的是居然升了3級,現在是6k水平,之前晚上下的多,停在9k挺長時間的,居然在10.1突破了,這麼看來我能升段的目標還是可能實現的,這麼看自信還真是挺重要的,而我一直不算個自信的人,本來打算10.1假期完成這個設計模式總結的,但是 ...
  • 是模型(model)-視圖(view)-控制器(controller)的縮寫,一種軟體設計典範,用一種業務邏輯、數據、界面顯示分離的方法組織, 在改進和個性化定製界面及用戶交互的同時,不需要重新編寫業務邏輯。M是指業務模型,V是指用戶界面,C則是控制器,使用MVC的目的是將M和V的實現代碼分離, 從 ...
  • A代碼編輯器,線上模版編輯,仿開發工具編輯器,pdf線上預覽,文件轉換編碼B 集成代碼生成器 [正反雙向](單表、主表、明細表、樹形表,快速開發利器)+快速表單構建器 freemaker模版技術 ,0個代碼不用寫,生成完整的一個模塊,帶頁面、建表sql腳本,處理類,service等完整模塊C 集成阿 ...
  • 本文會對可能用到的相關技術進行技術選型的說明,以及技術的架構介紹 ...
  • 寫在前面: 第一次配置時好好的,後來第二次改到MVC模式,把依賴註入寫成字典的單例模式時,由於新建的ORM(資料庫映射模型EF),怎麼弄都不用,一直報錯"No connection string named '**Context' could be found in the application ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...