C# Flyweight Pattern Kullanımı - OOP Design Pattern
Flyweight tasarım deseni; structural tasarım grubuna ait,
sık kullanılan nesnelerin bellek yönetimini kontrol etmek için kullanılan bir
tasarım desenidir. Dofactory.com a göre kullanım sıklığı %20 civarındadır.
FlyWeight tasarım
deseni bellek tüketimini optimize etmek amacıyla kullanıldığını
söylemiştik. Bu desende havuz mantığı söz konusudur. Örneğin kullanıcının
ekranda tıkladığı her x,y kordinatına çember çizen bir oyun yazdığımızı
düşünelim. Her tık için bir circle nesnesi yaratırsak bellek inanılmaz
şişecektir. Fakat bir circle nesnesi oluştursak ve kullanıcı tıkladığında bu nesnenin
x,y kordinatını değiştirip ekrana yazarsak sadece 1 nesne yaratarak bu programı
yazabiliriz. Bu tasarım kalıbında değerleri farklı olacak olan özelliklere extrinsic,
aynı olan özelliklere ise intrinsic denir.
Bir örnek
üzerinden tasarım desenimizi inceleyecek olursak örneğin ekran klavyesi
programı yazdığımızı düşünelim. Burada her basılan harf için yeni nesne
oluştursak belleğimiz şişecektir. Bunun yerine başta tüm harflerin nesnesini
oluştursak basılan harfın koduyla gidip havuzdan bu nesneyi çeksek harf
sayısı kadar nesne oluşturmamız bize yetecektir.
UML Diagram:
Kod:
/// <summary>
/// The 'Flyweight' abstract class
/// </summary>
public abstract class Character
{
//intrinsic
protected char symbol;
protected int keyKod;
//extrinsic
protected int pointIndex;
public abstract void Display(int pointIndex);
}
/// <summary>
/// A 'ConcreteFlyweight' class
/// </summary>
public class CharacterA:Character
{
public CharacterA()
{
this.symbol = 'A';
this.keyKod = 1;
}
public override void Display(int pointIndex)
{
this.pointIndex = pointIndex;
Console.WriteLine(this.symbol + " (pointIndex
" + this.pointIndex + ")");
}
}
/// <summary>
/// Z 'ConcreteFlyweight' class
/// </summary>
public class CharacterB:Character
{
public CharacterB()
{
this.symbol = 'B';
this.keyKod = 2;
}
public override void Display(int pointIndex)
{
this.pointIndex = pointIndex;
Console.WriteLine(this.symbol + " (pointIndex
" + this.pointIndex + ")");
}
}
/// <summary>
/// Z 'ConcreteFlyweight' class
/// </summary>
public class CharacterZ : Character
{
public CharacterZ()
{
this.symbol = 'Z';
this.keyKod = 29;
}
public override void Display(int pointIndex)
{
this.pointIndex = pointIndex;
Console.WriteLine(this.symbol + " (pointIndex
" + this.pointIndex + ")");
}
}
/// <summary>
/// The 'FlyweightFactory' class
/// </summary>
public class CharacterFactory
{
private Dictionary<char, Character> _characters = new Dictionary<char, Character>();
public Character GetCharacter(char key)
{
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;
}
}
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();
}
Çıktı:
0 yorum :
Yorum Gönder