The Flyweight design pattern uses sharing to support large numbers of fine-grained objects efficiently.
A visualization of the classes and objects participating in this pattern.
The classes and objects participating in this pattern include:
Character
)
CharacterA, CharacterB, ..., CharacterZ
)
CharacterFactory
)
FlyweightApp
)
This structural code demonstrates the Flyweight pattern in which a relatively small number of objects is shared many times by different clients.
using System;
using System.Collections.Generic;
namespace Flyweight.Structural
{
/// <summary>
/// Flyweight Design Pattern
/// </summary>
public class Program
{
public static void Main(string[] args)
{
// Arbitrary extrinsic state
int extrinsicstate = 22;
FlyweightFactory factory = new FlyweightFactory();
// Work with different flyweight instances
Flyweight fx = factory.GetFlyweight("X");
fx.Operation(--extrinsicstate);
Flyweight fy = factory.GetFlyweight("Y");
fy.Operation(--extrinsicstate);
Flyweight fz = factory.GetFlyweight("Z");
fz.Operation(--extrinsicstate);
UnsharedConcreteFlyweight fu = new
UnsharedConcreteFlyweight();
fu.Operation(--extrinsicstate);
// Wait for user
Console.ReadKey();
}
}
/// <summary>
/// The 'FlyweightFactory' class
/// </summary>
public class FlyweightFactory
{
private Dictionary<string, Flyweight> flyweights { get; set; } = new Dictionary<string, Flyweight>();
// Constructor
public FlyweightFactory()
{
flyweights.Add("X", new ConcreteFlyweight());
flyweights.Add("Y", new ConcreteFlyweight());
flyweights.Add("Z", new ConcreteFlyweight());
}
public Flyweight GetFlyweight(string key)
{
return ((Flyweight)flyweights[key]);
}
}
/// <summary>
/// The 'Flyweight' abstract class
/// </summary>
public abstract class Flyweight
{
public abstract void Operation(int extrinsicstate);
}
/// <summary>
/// The 'ConcreteFlyweight' class
/// </summary>
public class ConcreteFlyweight : Flyweight
{
public override void Operation(int extrinsicstate)
{
Console.WriteLine("ConcreteFlyweight: " + extrinsicstate);
}
}
/// <summary>
/// The 'UnsharedConcreteFlyweight' class
/// </summary>
public class UnsharedConcreteFlyweight : Flyweight
{
public override void Operation(int extrinsicstate)
{
Console.WriteLine("UnsharedConcreteFlyweight: " +
extrinsicstate);
}
}
}
This real-world code demonstrates the Flyweight pattern in which a relatively small number of Character objects is shared many times by a document that has potentially many characters.
using System;
using System.Collections.Generic;
namespace Flyweight.RealWorld
{
/// <summary>
/// Flyweight Design Pattern
/// </summary>
public class Program
{
public static void Main(string[] args)
{
// Build a document with text
string document = "AAZZBBZB";
char[] chars = document.ToCharArray();
CharacterFactory factory = new CharacterFactory();
// extrinsic state
int pointSize = 10;
// For each character use a flyweight object
foreach (char c in chars)
{
pointSize++;
Character character = factory.GetCharacter(c);
character.Display(pointSize);
}
// Wait for user
Console.ReadKey();
}
}
/// <summary>
/// The 'FlyweightFactory' class
/// </summary>
public class CharacterFactory
{
private Dictionary<char, Character> characters = new Dictionary<char, Character>();
public Character GetCharacter(char key)
{
// Uses "lazy initialization"
Character character = null;
if (characters.ContainsKey(key))
{
character = characters[key];
}
else
{
switch (key)
{
case 'A': character = new CharacterA(); break;
case 'B': character = new CharacterB(); break;
//...
case 'Z': character = new CharacterZ(); break;
}
characters.Add(key, character);
}
return character;
}
}
/// <summary>
/// The 'Flyweight' abstract class
/// </summary>
public abstract class Character
{
protected char symbol;
protected int width;
protected int height;
protected int ascent;
protected int descent;
protected int pointSize;
public abstract void Display(int pointSize);
}
/// <summary>
/// A 'ConcreteFlyweight' class
/// </summary>
public class CharacterA : Character
{
// Constructor
public CharacterA()
{
symbol = 'A';
height = 100;
width = 120;
ascent = 70;
descent = 0;
}
public override void Display(int pointSize)
{
this.pointSize = pointSize;
Console.WriteLine(symbol +
" (pointsize " + this.pointSize + ")");
}
}
/// <summary>
/// A 'ConcreteFlyweight' class
/// </summary>
public class CharacterB : Character
{
// Constructor
public CharacterB()
{
symbol = 'B';
height = 100;
width = 140;
ascent = 72;
descent = 0;
}
public override void Display(int pointSize)
{
this.pointSize = pointSize;
Console.WriteLine(this.symbol +
" (pointsize " + this.pointSize + ")");
}
}
// ... C, D, E, etc.
/// <summary>
/// A 'ConcreteFlyweight' class
/// </summary>
public class CharacterZ : Character
{
// Constructor
public CharacterZ()
{
symbol = 'Z';
height = 100;
width = 100;
ascent = 68;
descent = 0;
}
public override void Display(int pointSize)
{
this.pointSize = pointSize;
Console.WriteLine(this.symbol +
" (pointsize " + this.pointSize + ")");
}
}
}
The .NET optimized code demonstrates the
same real-world situation as above but uses modern, built-in .NET features,
such as, generics, reflection, LINQ, lambda functions, etc.
You can find an example on our Singleton pattern page.
All other patterns (and much more) are available in our Dofactory .NET product.
Not only does Dofactory .NET cover the Gang of Four and Enterprise patterns, it also includes
pattern architectures, low-code, and RAD (Rapid Application Development) techniques.
Accelerate development to where you can write
entire solutions in just 33 days!.
This unique package will change your developer lifestyle.
Here's what is included: