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