首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 設計模式無廢話系列(十):Flyweight 享元模式

     編輯:關於C#

意圖

運用共享技術有效支援大量細粒度對象。

適用場景

底層系統或框架常存在大量細粒度對象。遊戲中無數處使用模型數據,模型對象雖多但本質上只有幾種。引入 Flyweight 共享相同模型,大幅降低記憶體消耗。

完整範例程式碼

using System;
using System.Collections;
using System.Text;
using System.IO;

namespace FlyweightExample
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(GC.GetTotalMemory(false));
            Random rnd = new Random();
            ArrayList al = new ArrayList();
            for (int i = 0; i < 10000; i++)
            {
                string modelName = rnd.Next(2).ToString();
                Model model = ModelFactory.GetInstance().GetModel(modelName);
                // Model model = new Model(modelName); // 不使用享元
                al.Add(model);
            }
            Console.WriteLine(GC.GetTotalMemory(false));
            Console.ReadLine();
        }
    }
    class Model
    {
        byte[] data;
        public Model(string modelName) => data = File.ReadAllBytes($@"c:\{modelName}.txt");
    }
    class ModelFactory
    {
        Hashtable modelList = new Hashtable();
        static ModelFactory instance;
        public static ModelFactory GetInstance()
        {
            if (instance == null) instance = new ModelFactory();
            return instance;
        }
        public Model GetModel(string modelName)
        {
            Model model = modelList[modelName] as Model;
            if (model == null) modelList.Add(modelName, new Model(modelName));
            return modelList[modelName] as Model;
        }
    }
}

程式碼執行結果

使用享元模式記憶體佔用 不使用享元模式記憶體佔用

程式碼解析

  • ModelFactory:享元工廠,單例模式確保全域唯一,維護 Hashtable 管理享元實例。獲取時優先回傳已有實例,避免重複載入。
  • Model:享元角色,建構子從磁碟讀取模型數據至記憶體。
  • 執行結果顯示:未用享元時 10000 個對象佔用大量記憶體;用享元後僅 2 個模型實例,消除 9998 個重複對象。

何時採用

  • 系統有大量耗記憶體的細粒度對象,且對外無差別(或可改造為無差別)。

實作要點

  • 享元工廠維護享元實例表。
  • 享元不可共享狀態(外蕴狀態)需外部維護。
  • 視需求對享元角色抽象化。

注意事項

  • Flyweight 針對細粒度對象。若對象擁有大量獨立狀態,或非細粒度,不適合。維護大量外蕴狀態會增加邏輯複雜度且無法節省資源。
  • 工廠維護實例列表同樣佔用資源。若享元本身資源極小、實例數不多(與列表元素數相近),得不償失。關鍵在於權衡得失。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved