TASARIM DESENLERİ YAZI DİZİSİ 5-Singleton (Tek Nesne)

Creational Patterns (Yaratıcı Tasarım Desenleri) grubu altında yeralan Singleton tasarım deseni üretilmek istenen bir nesnenin yazılan programın açık olduğu sürece sadece bir kez oluşturulmasını ve bu sayede diğer zamanlarda nesne yeniden üretilmeyerek var olan nesnenin kullanılmasını sağlamaktadır.

Bu durumun bize kazandırdığını şu şekildeki bir senaryo ile daha kolay kavrayabiliriz.

Elimizde bir prizimizin var olduğunu düşünelim. Bu prizimize öncelikle telefonumuza ait şarj aletimizi takıyoruz ve işimiz bittiğinde bunu çıkartarak aynı prize Televizyonumuza ait fişimizi takabiliyoruz.

Çok normal bir durum öyle değil mi? Peki şu şekilde bir durum söz konusu olsaydı nasıl olurdu?

Telefonumuzun şarj aletini taktık işimiz bitti ve prizimizi değiştirmek zorunda kalarak yeni bir priz elde ediyoruz ve televizyonumuzu bu yeni prize takıyoruz. Hatta televizyon ile işimiz bittiğinde de farklı bir elektrikli aleti kullanmamız için yeniden bir priz daha elde etmemiz gerekiyor.

Bu durum düşünceye biraz ters geliyor değil mi? Sonuçta biz sürekli aynı işi yapan (elektrik veren) bir aracı kullanarak bize sunduğu elektriği çeşitli aletlerimizde kullanıyoruz. Peki yazdığımız programlarda sürekli aynı işi yapan bir yapı için her kullanımda yeni bir nesne üretilmesi ne derece doğru?

İşte bu gibi durumları en güzel biçimde çözümleyebilmek için singleton tasarım deseni biçilmiş kaftandır.

Şimdi belirtmiş olduğumuz priz yapımızı Singleton Tasarım Deseni ile tasarlayalım.

İlk yapmamız gereken prizimize ait üyelerden PrizID özelliği hariç tümünü dışarıdan erişilememesi için private olarak tanımlamak olacaktır.

private static Priz _Priz;
private static object KullanimDurumu = new object();
private static string _PrizID;
 
public string PrizID
{
    get
    {
        return _PrizID;
    }
}
 
private Priz(string PrizID)
{
    _PrizID = PrizID;
}

Bu üyelerimizden;
• _Priz değişkeni Priz classımıza ait nesneyi (classın kendisini) barındıran değişkendir.

• KullanimDurumu değişkeni prizimizin o anda aktif olarak kullanılıp kullanılmadığını (multi thread uygulamalar da aynı anda birden çok erişim anında kontrollü bir biçimde nesneyi kullandırabilmek için) barındıran değişkendir.

• _PrizID değişkeni aslında lazım olmayan ancak şu anki senaryomuzda her seferinde aynı prizi kullandığımızı belirlememizi sağlayan prize ait benzersiz id değerini barındıran değişkendir.

• PrizID adlı özelliğimiz ise yukarıdaki benzersiz ID mizi geriye döndürmemizi sağlamaktadır.

• Son olarak classımızdan dışarıdan ulaşılarak yeni bir nesne üretilmesini engellemek amacıyla classımıza ait constructure metodumuzu da private olarak tanımlıyoruz.

Prizimize ait üyelerimizin tanımımızı yaptıktan sonra artık prizimizin kullanımını sağlayacak olan metodumuzu yazabiliriz.

public static Priz PrizKullan()
{
    if (_Priz==null)
    {
        lock (KullanimDurumu)
        {
            if (_Priz == null)
            {
                _Priz = new Priz(Guid.NewGuid().ToString());
            }
        }
    }
    return _Priz;
}

Prizimizin kullanımı sağlayan metodumuzda sırasıyla;

Eğer _Priz değişkeni tanımsız ise (daha önceden classımızdan yeni bir nesne tanımlanmadıysa) öncelikle kullanım durumuna bakılmaktadır. Bunun sebebi eğer o anda farklı bir alandan bu nesneye aynı anda birden çok erişim varsa hepsi için tekrar tekrar nesne üretilmek yerine sadece birisi için nesne üretilsin ve diğerleri için üretilmiş olan nesne kullanılsın diyedir.

Eğer farklı bir alandan bu nesneye erişim sağlandıysa lock anahtar sözcüğüyle işlem kitlenmektedir. Ancak bu durumda da nesne üretilmemiş olabilir bu sebep ile lock anahtar sözcüğü içerisinde yeniden _Priz değişkeninin tanımlı olup olmadığı kontrol edilmektedir.

Eğer burada da tanımsız ise yeni bir nesne oluşturularak nesneye bir benzersiz id atanmaktadır.

Tüm işlemler bittikten sonra ise oluşturulan veya daha önce oluşturulmuş olan nesnemiz geriye döndürülmektedir.

Artık prizimizi kullanmaya başlayarak birden çok kullanımda aynı priz olup olmadığını kontrol edebilecek kodumuzu yazabiliriz.

Priz sarjAleti=Priz.PrizKullan()
Console.WriteLine(sarjAletş.PrizID)

singleton
Hazırladığımız tasarım desenimiz sayesinde new anahtar sözcüğünü kullanmadan nesnemizi tanımlayabiliyoruz. Bu durum karşısında desenimiz eğer daha önceden nesnemiz tanımlı değilse yeni nesne oluşturularak bu nesneyi veya tanımlı ise önceden tanımlanmış olan nesneyi geriye döndürmektedir.

Bunu da her iki kullanımdaki nesnemize ait id değerini ekrana yazdırdığımızda aynı değerin yazılması sebebiyle sağlamasını yaparak tespit etmekteyiz.

Bu makalede kullanılan tasarım desenine ait kodu indirmek için ………..

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.