Flyweight Design Pattern
By Peter Bromberg
Use sharing to support large numbers of fine-grained objects efficiently.
The Flyweight Pattern is hardly used in business application development. However, it is valuable as a memory management technique when many objects are created with similar state. Internally, .NET uses Flyweights for strings that are declared at compile time and have the same sequence of characters. The stateless flyweights refer to the same memory location that holds the immutable string.
using System;
using System.Collections.Generic;
namespace Patterns
{
class
MainApp
{
static
void Main()
{
//
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)
{
Character
character = factory[c];
character.Display(++pointSize);
}
//
Wait for user
Console.ReadKey();
}
}
///
<summary>
/// The 'FlyweightFactory' class
/// </summary>
class CharacterFactory
{
private Dictionary<char, Character> _characters =
new Dictionary<char, Character>();
// Character indexer
public Character this[char key]
{
get
{
// Uses "lazy initialization" -- i.e. only create when needed.
Character
character = null;
if (_characters.ContainsKey(key))
{
character
= _characters[key];
}
else
{
// Instead of a case statement with 26 cases (characters).
// First, get qualified class name, then dynamically create instance
string name = this.GetType().Namespace + "." +
"Character" + key.ToString();
character
= (Character)Activator.CreateInstance
(Type.GetType(name));
}
return character;
}
}
}
/// <summary>
/// The 'Flyweight' class
/// </summary>
class Character
{
protected char symbol;
protected int width;
protected int height;
protected int ascent;
protected int descent;
public void Display(int pointSize)
{
Console.WriteLine(this.symbol +
" (pointsize " + pointSize + ")");
}
}
/// <summary>
/// A 'ConcreteFlyweight' class
/// </summary>
class CharacterA : Character
{
// Constructor
public CharacterA()
{
this.symbol = 'A';
this.height = 100;
this.width = 120;
this.ascent = 70;
this.descent = 0;
}
}
/// <summary>
/// A 'ConcreteFlyweight' class
/// </summary>
class CharacterB : Character
{
// Constructor
public CharacterB()
{
this.symbol = 'B';
this.height = 100;
this.width = 140;
this.ascent = 72;
this.descent = 0;
}
}
// ... C, D, E, etc.
/// <summary>
/// A 'ConcreteFlyweight' class
/// </summary>
class CharacterZ : Character
{
// Constructor
public CharacterZ()
{
this.symbol = 'Z';
this.height = 100;
this.width = 100;
this.ascent = 68;
this.descent = 0;
}
}
}
Flyweight Design Pattern (503 Views)