Yazılım Mimarileri ve Tasarım Desenleri Üzerine

C# Singleton Design Pattern(Singleton Tasarım Deseni)

Bu yazımda C#’ta Singleton Design Pattern kullanımını anlatmaya çalışacağım.Yazılım dünyasın da bir çok tasarım deseni mevcuttur.Nesnenin oluşturulması ve yönetilmesiyle ilgili olan Creatinal Patterns grubundan Singleton desenini anlatmaya çalışacağım.Diğer desenlerle ilgili yazılar ilerideki zamanlar da hazırlamayı düşünüyorum.
Singleton Deseni
Bu yapıda kullanıcıya kendi başına bir nesne yaratma izni verilmez.Kullanıcı bizden sadece nesne talep edebilir.Ve bizden nesne talep ettiğinde de biz ona her defasında bellekte var olan nesneyi veririz.Böylece kullanıcı sadece tek bir nesne ile çalışmak zorunda kalır.Yani kullanıcı bir iş için 50 tane farklı nesne üretemez.
Mesela SqlConnection nesnesini bazı durumlar da çok üretmek zorunda kalıyoruz.Birden fazla SqlConnection nesnesi üretip belleğe yük bindireceğimize var olan SqlConnection nesnesi üzerinden işlem yapmamız performans açısından olumlu olacaktır.
Peki bu işi nasıl yapacağız?
Öncelikle kullanıcıya nesne yarattırmamız gerektiği bariz ortada.
Bunu sağlayabilmek için Constructor private yapılarak, kullanıcın nesne yaratması engellenir.
Kullanıcı constructor kullanarak nesne yaratamayacağı için, nesneyi ona biz vermeliyiz.Bu da ancak o class tipinde bir nesne gönderen static bir metod ya da özellikle(property) mevcuttur.
Kullanıcıya bu metod ya da property her defasında aynı nesneyi göndermeli.
Bu yüzden metod ya da property içinde if kontrolüyle aynı nesneyi göndermeyi sağlayacağız.

Şimdi ben Singleton.cs adında bir class oluşturuyorum.Ve bu classı yukarda anlattığım şekilde constructorını private yapıp,Singleton classından nesne oluşturulmasını engelliyorum.Singleton tipinde geri dönüş değeri olan,static bir metod yazıp kontrollerle her defasında aynı nesneyi gönderiyorum.Bir kereliğine oluşturmaya mahsus.
1.YOL

    class Singleton
    {
        private Singleton()
        {

        }
        private static Singleton nesne;
//static metodun içinde bu referansı kullanabilmemiz için static olması gerekiyor.
//static metodun içinde sadece static metodlar kullanılabilir.
        public static Singleton NesneVer()
        {
            if (nesne==null)
            {
                nesnem = new Singleton();
            }
            return nesne;
        }
    }

Yukarıdaki kod bloğunu izah edeyim.Boş constructoru private yaparak başka classta new operatörüyle yeni bir nesne yaratılmasını engelliyoruz.O constructorı bu classta kullanabiliriz.Bir tane static Singleton tipinde nesnem adında referans oluşturuyoruz.Ama hemen nesneyi ona bağlamıyoruz.Çünkü Singleton tipinde geri dönen static metodumuz da kontrollü bir şekilde bağlayacağız.
Eğer nesnem adındaki referansımız null değerine sahipse nesnem referansına bir Singleton nesnesi bağlıyoruz ve bunu return ediyoruz.
Şimdi sunum katmanın da bu sınıftan nesne nasıl çağırıyoruz ona bakalım.

Singleton nesne = new Singleton();
//Bu şekilde nesne oluşturamazsınız.Hata alırsınız...
Singleton nesne = Singleton.NesneVer();
//Bu şekilde Singleton dönen static metodu çağırarak nesneyi oluşturabilirsiniz.

Şimdi Singleton.cs sınıfından iki nesne oluşturalım.Bakalım bu sınıftan oluşturduğumuz nesnelerin hepsi bir tek aynı nesneyimi gösteriyor.

Singleton nesne1 = Singleton.NesneVer();
Singleton nesne2 = Singleton.NesneVer();

Gördüğünüz gibi nesne1 ve nesne2 referanslarına Singleton sınıfındaki NesneVer() static metoduyla nesne verdik.Bakalım bu iki referansta aynı nesneyimi gösteriyor.
Bir çok yöntemle bunu test edebiliriz.
Test 1

            if (nesne1==nesne2)
            {
                MessageBox.Show("Test");
            }

Test 2

            if (nesne1.Equals(nesne2))
            {
                MessageBox.Show("Test");
            }

Test 3

            if (nesne1.GetHashCode()==nesne2.GetHashCode())
            {
                MessageBox.Show("Test");
            }

GetHashCode() : Bu metot geriye nesnenin bellekteki adresini döndürür.Dolayısıyla bu if çalışırsa referanslar aynı nesneyi gösteriyor deriz
Yukarıdaki herhangi bir test sonucunda mesaj kutusunda “Test” yazısını göreceksiniz.
Singleton Design Pattern’in bir başka yöntemi de diğer sayfa da anlatılmıştır.

1. sayfa da anlatılan Singleton Design Pattern yönetimi , Constructor’ı private yaptıktan sonra , geriye Singleton tipinde değer dönen static metodumuz da kontrollü bir şekilde nesne oluşturup gönderiyorduk.Eğer nesne yoksa oluşturup gönderiyorduk.Eğer nesne varsa var olan nesneyi gönderiyorduk.
Şimdi ise aynı mantıkta static property ile çalışacağız.
Bu yöntemi de Singleton.cs classında hazırlayacağım.
2.YOL

    class Singleton
    {
        private Singleton()
        { }
        private static Singleton nesnem;
//static yapı içerisinde kullanacağımız için bunun da static olması gerekiyor.
//static yapılarlar içinde kullanılanlar static olmalıdırlar.
        public static Singleton NesneVer
        {
            get { return nesnem; }
        }

        static Singleton()
        {
            nesnem = new Singleton();
        }

    }

Yukarıdaki kod bloğundaki mantığa değineyim.Constructorı private yapılarak,dışarıda bu class üzerinden nesne yaratılmasını engelliyoruz.Singleton tipinde static bir private refenrans oluşturuyorum.Bu referansı dışarıya kontrollü açmak için public tipinde gerite Singleton dönen statik Nesne adlı propertymi yazıyorum.Bu propertyi bize sadece nesneyi göndereceği için set bloğunu kaldırıyorum.Sonra static constructor oluşturuyorum.Bu static constructorın özelliklerinden hatırlarsanız eğer, static elemanlardan biri çalıştırılmaya kalkışıldığı zaman ondan önce çalışır.Ve bir kere çalışır.Bir daha çalışmaz.Bu sebepten dolayı Singleton orneknesne = Singleton.Nesne dediğimiz zaman, ilk static constructor çalışacağı için bir nesne oluşturacaktır.Ve bu nesneyi Singleton tipteki nesnem referansına bağlayacaktır.Ve property sayesinde o nesneyi orneknesne referansına bağlıyacaktır.Singleton sınıfından ikinci bir nesne oluşturulduğun da static yapıcı metodumuz çalışmayacağı için nesnem referansına başka bir nesne bağlanmayacak ve daha önceden var olan nesne property sayesinde gönderilecektir.
Şimdi Singleton sınıfından iki nesne çağıralım.

            Singleton nesnem1 = Singleton.Nesne;
            Singleton nesnem2 = Singleton.Nesne;

            if (nesnem1.GetHashCode()==nesnem2.GetHashCode())
            {
                MessageBox.Show("Test");
            }

Yukarıda çağrılan nesnelerin aynı olup olmadığı denetlenmiştir.Ve sizde denerseniz “Test” yazısını göreceksiniz.Buda bir ispattır.
Şimdilik bu kadar.Bir sonraki yazım da görüşmek üzere.
İyi çalışmalar…

Exit mobile version