Design Patterns: Flyweight

The Flyweight Design Pattern allows you to share instances of the same object across multiple calls.

In the example on this post I will be reusing a rectangle with the same color, that makes the color property “intrinsic”. But I will not share position and size across the instances, so those characteristics are “extrinsic”.

  1. namespace ConsoleApplication1  
  2. {  
  3.     class Program  
  4.     {  
  5.         static void Main(string[] args)  
  6.         {  
  7.             var r = FlyweightFactory.Create("Red");  
  8.             var g = FlyweightFactory.Create("Green");  
  9.             var b = FlyweightFactory.Create("Blue");  
  10.    
  11.             r.Draw(0, 0, 10, 10);  
  12.             r.Draw(0, 0, 20, 30);  
  13.    
  14.             g.Draw(0, 0, 20, 30);  
  15.             FlyweightFactory.Create("Green").Draw(10, 20, 50, 70);  
  16.    
  17.             b.Draw(0, 0, 20, 30);  
  18.    
  19.             FlyweightFactory.Create("Purple").Draw(10, 20, 50, 70);  
  20.    
  21.             Console.ReadKey(true);  
  22.         }  
  23.     }  
  24.    
  25.     public class FlyweightFactory  
  26.     {  
  27.         private static ConcurrentDictionary<string, Rectangle> cache  
  28.             = new ConcurrentDictionary<string, Rectangle>();  
  29.    
  30.         public static Rectangle Create(string key)  
  31.         {  
  32.             return cache.GetOrAdd(key, new Rectangle(key));  
  33.         }  
  34.     }  
  35.    
  36.     public class Rectangle  
  37.     {  
  38.         public Guid ID { getset; }  
  39.    
  40.         public string ColorName { getset; }  
  41.    
  42.         public Rectangle(string name)  
  43.         {  
  44.             ID = Guid.NewGuid();  
  45.             ColorName = name;  
  46.         }  
  47.    
  48.         public void Draw(int x, int y, int width, int height)  
  49.         {  
  50.             Console.WriteLine("Rectangle ({0}) instance: {1}"  
  51.                               , ColorName, ID);  
  52.             Console.WriteLine("X: {0} Y: {1} W: {2} H: {3}"  
  53.                               , x, y, width, height);  
  54.             Console.WriteLine();  
  55.         }  
  56.     }  
  57. }  

Output:

Flyweight

In a real world example: You could use it in game development. Imagine that you have a system to change a character’s clothes, you don’t need to create an instance of the character itself entirely, having to load expensive resources every time. You could just use a shared instance of the character’s model and have the clothes as the extrinsic part. (And hey, you could have another Flyweight system to reuse clothes instances as well).

Next Recommended Reading Design Patterns in C#