iT邦幫忙

2022 iThome 鐵人賽

DAY 23
1

Flyweight模式又稱享元模式,顧名思義就是共享元件,它使用物件用來儘可能減少記憶體使用量,於相似物件中分享儘可能多的資訊。我們第19天的Object Pool模式是在做物件重複使用的共享,但不會去改變到物件本身的狀態。

今天介紹的享元模式,就是重複使用同一個元件,並且能做狀態上的變更。這樣的好處是如果要很頻繁的建立很類似的物件,只是狀態的改變,但本質上是一樣的,就能夠減少記憶體使用量,進而提高資源使用率。

Flyweight - 定義

共享物件,用來儘可能減少記憶體使用量以及分享資訊給儘可能多的相似物件。

https://ithelp.ithome.com.tw/upload/images/20220927/20136443BNLwJqSyCp.png

(圖片來源:https://ducmanhphan.github.io/img/design-pattern/flyweight-pattern/uml-flyweight.png)

範例 UML

https://ithelp.ithome.com.tw/upload/images/20220927/20136443pTKEE0W4FG.png

Code要點

  • ShapeFactory負責創建和管理各個顏色的圓形,如果GetCircle 呼叫時發現某顏色的圓形尚未被建立過,則會建立實例,並且記錄到circleMap,反之如果在circleMap裡能夠找到已建立過的顏色圓形,就將它回傳。

不囉嗦上Code!

using System;
using System.Collections.Generic;

namespace DAY23_Flyweight
{
    public class Program
    {
        public static void Main(string[] args)
        {
            for (int i = 0; i < 15; ++i)
            {
                Circle circle = (Circle)ShapeFactory.GetCircle(GetRandomColor(), GetRandomX(), GetRandomY());
                circle.GetNewSite();
            }
        }

        public static List<string> colors = new List<string> { "Red", "Green", "Blue", "White", "Black" };
        public static Random rnd = new Random();
        public static string GetRandomColor()
        {
            return colors[(int)(rnd.Next(colors.Count-1))];
        }
        public static int GetRandomX()
        {
            return rnd.Next(1000);
        }
        public static int GetRandomY()
        {
            return rnd.Next(1000);
        }
    }

    public interface IShape
    {
        void GetNewSite();
    }

    public class Circle : IShape
    {
        public string Color { get; set; }
        public int X { get; set; }
        public int Y { get; set; }

        public Circle(string color, int x, int y)
        {
            Color = color;
            X = x;
            Y = y;
        }

        public void GetNewSite()
        {
           Console.WriteLine($"顏色:{Color} | 新座標位置 => x:{X}, y:{Y}");
        }
    }

    public class ShapeFactory
    {
        // 儲存已有的顏色圓形
        private static readonly Dictionary<string, IShape> circleMap = new Dictionary<string, IShape>();

        public static IShape GetCircle(string color, int x, int y)
        {
            Circle circle = (Circle)circleMap.GetValueOrDefault(color);

            // 沒有建造過的顏色圓形,就新增一個新的,有的話就使用已有的顏色圓形
            if (circle == null)
            {
                circle = new Circle(color, x, y);
                circleMap.Add(color, circle);
                Console.Write($"建造基底圓形 | ");
            }
            else
            {
                Console.Write($"重複使用圓形,改成不同座標!舊座標位置 => x:{circle.X}, y:{circle.Y} | ");
                circle.X = x;
                circle.Y = y;
            }
            return circle;
        }
    }
}
  • 結果

https://ithelp.ithome.com.tw/upload/images/20220927/20136443oLlcdQm6CH.png

簡單的小結

透過 Flyweight模式,相同的物件只需要保存一份,降低了系統中的物件數量,也跟著降低系統記憶體的壓力,適用於一個系統中有大量的物件,這些物件會耗費大量的記憶體的情況。


上一篇
【DAY22】Composite模式 - 從種子到大樹的過程
下一篇
【DAY24】Proxy模式 - 找個代理人來幫忙你吧!
系列文
勇闖秘境!探索物件導向背後的設計模式30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言