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).