C# State Pattern Kullanımı - OOP Design Pattern

State tasarım deseni behavior grubununa ait, nesnelerin farklı durumlarda farklı çalışmalarını düzenleyen bir tasarım desenidir. dofactory.com sitesine göre kullanım sıklığı %60 civarındadır.



Örneğin bir kahve makinası düşünün önce duğmesine basarız hazırlanıyor yazar ekranda bu makinanın hazırlanıyor durumuna geçtiğini gösterir bu durumda su kaynatılır kahve eklenir. Ardından kahve hazırdır bardağa boşaltma kısmı gelir. Bu durumda kahve bardağa boşaltılır bitirme durumundadır makina bu sefer. Görüldüğü gibi makina farklı durumlarda farklı işlemler yapmaktadır. Bu patternin amacıda bunun gibi nesnenin farklı durumlarında farklı çalışmaların yapılmasını sağlamaktır.

Bir başka örnek bankacılık sektöründen verilebilir mesela bir müşterinin hesabındaki parası bir sınırı geçince gold müşteri statüsünde olacaktır ve verilen faiz oranı değişecektir. Bu durumda da bu pattern kullanılabilir.

Örnek kodumuzu basit bir server otomasyonu yaparak yazmayı düşündüm. Örnekte contex nesnemiz olarak bir server’ımız var ve CPU değeri %80 in üzerine çıkınca status OverloadState durumuna geliyor ve bu statüde iken yeniden stabil duruma geçmek için bir takım programları kapatıyor ve yeniden stabil olunca ise OKState durumuna geçiyor.

UML Şema:

Kod:
     /// 
    /// State abstract class
    /// 
    public abstract class ServerState
    {
        public abstract void HandleState(Server context);
    }

    /// 
    /// Concrete State
    /// 
    public class OverloadState:ServerState
    {
        public override void HandleState(Server context)
        {
            Console.WriteLine(@"Server CPULevel is: {0}. Server state 
                 is overload. Some programs is closing.", context.CPULevel);
            context.CloseProgram(5);
            if (context.CPULevel > 80)
                context.State = new OverloadState();
            else
                context.State = new OkState();
        }
    }

    /// 
    /// Concrete State
    /// 
    public class OkState:ServerState
    {
        public override void HandleState(Server context)
        {
            Console.WriteLine(@"Server CPULevel is: {0}. Server state 
                   is OK."
                   ,context.CPULevel);
        }
    }

/// 
    /// Context class
    /// 
    public class Server
    {
        public int CPULevel { get; set; }

        private ServerState _state;
        public ServerState State
        {
            get { return _state; }
            set
            {
                _state = value;
                // Burada durum değişimleri sonucu çalıştırılacak 
                // davranışların başlatılma noktasınıda 
                // merkezileştirmiş oluyoruz.
                _state.HandleState(this);
            }
        }

        public Server()
        {
            this.CPULevel = 50;
            ControlServerCPULevel();
        }

        public void ControlServerCPULevel()
        {
            if (this.CPULevel > 80)
                this.State = new OverloadState();
            else
                this.State = new OkState();
        }

        public void CloseProgram(int programUsageCPU)
        {
            this.CPULevel -= programUsageCPU;
        }

        public void AddProgram(int programUsageCPU)
        {
            this.CPULevel += programUsageCPU;
            ControlServerCPULevel();
        }
    }

        static void Main(string[] args)
        {
            Server server = new Server();
            server.AddProgram(20);
            server.AddProgram(10);
            server.AddProgram(30);

            Console.ReadLine();

        }


Çıktı:

0 yorum :

Yorum Gönder