Design Pattern Serisi 1: Singleton

Herkese merhaba, öncelikle neden başlıkta ingilizce terimler kullandığıma değinmek istiyorum. Yazılım dünyasında ağırlıklı dilin ingilizce olduğu ve bu tür terimlerin türkçe karşılığı bana çok anlamlı gelmediği için bu şekilde başlık atma gereği duydum. Design Pattern için Tasarım Deseni çevirisi yapılabilir. Belki TDK buna farklı bir isim verirse daha güzel olabilir ancak ben yine de bu tür ünlü terimleri ingilizce bırakarak makale serime devam etmek istiyorum.

Makale serimi C# üzerinde uygulayacağım. Ve .NET Core platformu üzerinden göstereceğim. Burada gerçekleştirilmiş tüm kodlara bu linkten Github ulaşabilirsiniz.

Singleton Pattern

Bu design pattern en basit olanlarından biridir. Varsayalımki projenizde öyle bir sınıfa ihtiyaç var ki sadece sizin tarafınızda oluşturulup tek bir noktadan kullanılmasını istiyorsunuz. Bu durumda bu design pattern devreye giriyor ve küçük nüanslarla bizi büyük dertlerden kurtarabiliyor. Elde etmek istediğimiz yapı sol taraftaki Class Diagram’ında gösterilmektedir. Öncelikle ilk aşamadan başlayarak örnek sınıfımızı oluşturup gösterelim. Daha sonra bu sınıfı adım adım nasıl Singleton Pattern yapacağımızı görelim.

Aksiyon geçmişini hafızada tutan ve gerektiği zaman kaydedebilen bir sınıf oluşturdum. Böyle bir sınıfın bir projede tek bir elden kullanılması doğru bir yaklaşım sağlayacaktır. Yukarıdaki hali ile kullanmak istersek sadece yeni bir instance açmamız bize kullanımını sağlayacaktır. Ancak, bu sınıf birden fazla oluşturulursa her bir instance kendine ait Stack<string> tutacaktır ve ona göre dosyaya kaydetme işlemi yapacaktır ancak biz bunu istemiyoruz.

Öncelikle, Singleton Pattern’ın en can alıcı kısmı constructor kısmının erişebilirlik düzeyini public den private yapmamız gerekmekte. Bu sayede bu sınıfı kendi içi dışında hiç bir yerde oluşturamayacağız. Oluşturmaya çalıştığımızda da bu hata ile karşılaşacağız.

ActionHistory_V1.ActionHistory_V1()’ is inaccessible due to its protection level

Bu yaklaşım ile bu sınıfı sadece tek bir yerde yani kendi içinde oluşturabileceğiz. Sınıfı bu şekilde düzenleyebiliriz.

Bu şekilde projede aşağıdaki şekilde kullanımı sağlanacaktır. Sınıf içerisinde buluna Instance özelliğine erişerek sınıfı elde etmemiz yetecektir. Daha sonrasında sınıfı istediğimiz şekilde kullanmamız için hazır.

Ancak burada da bir sorun ile karşılaşıyoruz, o da bu oluşturduğumuz sınıf daha ağır yüklü bi sınıf olabilir o yüzden programın başlangıcında oluşturulması (static olarak tanımladığımız ve oluşturduğumuz için program açıldığında sınıfı oluşturacaktır.), programın açılış süresini etkileyebilir. Bunun için Instance özelliği (property) ilk istenildiğinde oluşturulması akılcı bir çözüm olabilir. Daha bitmedi ! burada aynı anda birden fazla erişim yapılırsa instance birden fazla oluşturulabilir, o yüzden bu kısmın Critical Sectionolarak dikkate alınması gerekmektedir. Bu yüzden o kod bloğunu lock keywordu ile kilitleyip thread-safe yapabiliriz. Ancak ben sizi bunlarla uğraştırmayacağım.

.NET de bulunan Lazy<T> yapısını kullanarak, bu objenin hem istenildiği zamanda hem de thread-safe olarak oluşturulmasını sağlayacağız.

Bu çözüm ile birlikte ilk kullanım sırasında, gerektiğinde sınıfı oluşturacak ve programın açılış hızında yavaşlama sağlamayacaktır. Yine de bu yaklaşımda her sınıfa göre değişebilir. Siz kendi sınıfınızın amacına ve özelliklerine göre ayrı bir şekilde tasarım yapmanız gerekebilir. Bu yüzden bu tür yaklaşımlarda kurallara uymak yerine kuralları esneterek kendinize göre bir çözüm üretmeniz gerekecektir.

Yukarıdaki kodların tamamlanmış haline buradan erişebilirsiniz. Bir sonraki yazıda görüşmek üzere.

Kaynaklar

ITU. CE. LCWaikiki www.alimozdemir.com