Flyweight模式又稱享元模式,顧名思義就是共享元件,它使用物件用來儘可能減少記憶體使用量,於相似物件中分享儘可能多的資訊。我們第19天的Object Pool模式是在做物件重複使用的共享,但不會去改變到物件本身的狀態。
今天介紹的享元模式,就是重複使用同一個元件,並且能做狀態上的變更。這樣的好處是如果要很頻繁的建立很類似的物件,只是狀態的改變,但本質上是一樣的,就能夠減少記憶體使用量,進而提高資源使用率。
共享物件,用來儘可能減少記憶體使用量以及分享資訊給儘可能多的相似物件。
(圖片來源:https://ducmanhphan.github.io/img/design-pattern/flyweight-pattern/uml-flyweight.png)
ShapeFactory
負責創建和管理各個顏色的圓形,如果GetCircle
呼叫時發現某顏色的圓形尚未被建立過,則會建立實例,並且記錄到circleMap
,反之如果在circleMap
裡能夠找到已建立過的顏色圓形,就將它回傳。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;
}
}
}
透過 Flyweight模式,相同的物件只需要保存一份,降低了系統中的物件數量,也跟著降低系統記憶體的壓力,適用於一個系統中有大量的物件,這些物件會耗費大量的記憶體的情況。