Singleton Design Pattern

Creational Design Patterns > Singleton Design Pattern

Bu içeriğin artık modasının geçtiğini yani artık kullanılmadığının altını çizeyim. (Microsoft öyle söylüyor)

Sıklıkla kullandığınız sabit içerikli methodlarımızı tekrar tekrar yazarak RAM işgal edecek şekilde çalıştırmak yerine tek seferde yazarak ve tek seferde çalıştırarak hem RAM den hem de zamandan tasarruf etmemizi sağlıyor.

Singleton nesneler ilk çağırıldıklarında bir kez oluşturulur ve sonraki çağırmalarda ilk oluşturulan nesne döndürülür.

Teorik bilgi: Her bir obje “new” çağrısıyla bir kopyası RAM’e kaydedilir ve daha sonra farklı yerlerde çağırılır. Aynı işlem RAM ‘de birden fazla yer işgal etmesini önlemek hedeflenir. Ayrıca güvenlik konusunda ayrı bir sınıfta işlendiği için daha güvenli sayılabilir.

Hangi durumlarda kullanılır:

Sunucu ile Database bağlantısı yapılacaktır, bu bağlantıyı tekrar tekrar çalıştırılarak artan RAM kullanımımın düşmesini istiyorum.

Hangi durumlarda kullanılmaz:

Eğer üzerinde kilitleme uygulanırsa kullanıcı girişi uygulamasında kullanılmaz.

Ek bilgi: Bu yapı “Lazy Initialization” yani geç başlatma olarak adlandırılan yöntemle çalışır, anaprogram çalışınca değil kendisi çağırılınca çalışır, kodunuz gerekmediği sürece çalışmaz.

Örnek uygulama: Console.app üzerinden
//SingletonSample.cs
namespace Singleton
{
    class SingletonSample //DB connection
    {
        private SingletonSample() { }
        private static volatile germanDBEntities db;
        public static germanDBEntities germanDBEntities
        {
            get
            {
                if (db == null)  //db boşsa
                {
                    // DB bağlantısını çalıştır
                    db = new germanDBEntities();
                    Console.WriteLine("DB bağlantısı oluşturuldu.");
                }

                Console.WriteLine("DB bağlantısı istendi.");
                return db;
            }
        }
    }
}
//Program.cs
namespace Singleton
{
    class Program
    {
        static void Main(string[] args)
        {
            germanDBEntities db;

            db = SingletonSample.germanDBEntities;

            Console.WriteLine(db.dictionary.FirstOrDefault().german);
            Console.ReadKey();
            Console.WriteLine(db.dictionary.Find(2).german);
            Console.ReadKey();
        }
    }
}

sonuç aşağıdaki gibi olacaktır.

DB için iki farklı sorgu yaptım, ilk seferinde db değişkeni boş olduğu için new çağrısıyla oluşturdu, çalıştırarak RAM ‘e attı, bir sonrakinde ise RAM ‘den çekerek yeniden sorgu oluşturmadı. Bu olay özellikle birden fazla istemcinin sorguya yüklenmesinde işe yarıyor. Biraz daha anlatıcı olmak gerekirse, 1. istemci sistemdeki ürünleri çekerken sorgu çalıştırmak zorunda, basit bir db sorgusuyla RAM ‘de 1. istemci için yer açılır, sonrasında 2. istemci de ürünleri listelemek istedi onun için RAM üzerinde farklı bir yer açılır.
Ama Singleton uygulanırsa 1. istemcinin yaptığı sorgunun RAM’deki yerini tutup 2. istemciye iletirsek hem DB bağlantısından hem de RAM alanından tasarruf etmiş oluruz.

Yukarıdaki örnekte ilk bağlantı kontrol ediliyor, eğer yoksa bağlantı oluşuyor. Bu durum aynı anda bu sınıfı çalıştıran iki kullanıcının da ilk sorguyu çalıştırabileceği anlamına geliyor, bunun olmaması için aşağıdaki gibi bir düzenleme yapmak gerekir.
 Double-Check Locking [Lea99]

namespace Singleton.Contents
{
    class SingletonSample //DB connection
    {
        private SingletonSample() { }
        static object _lock = new object();
        private static volatile germanDBEntities db;
        public static germanDBEntities germanDBEntities
        {
            get
            {
                if (db == null)
                {
                    lock (_lock)//ilk çalıştıran haricinde giremez
                    {
                        if (db == null)
                            db = new germanDBEntities();
                        Console.WriteLine("DB bağlantısı oluşturuldu.");
                    }
                }
                Console.WriteLine("DB bağlantısı istendi.");
                return db;
            }
        }
    }
}

Başka bir örnek ise, e-ticaret sitem var ve içinde milyonlarca ürün var. Her seferinde sunucuya sorgu göndermesini istemiyorum bu verileri RAM ‘de tutmasını istiyorum (bu sayede veri daha hızlı dönecek, sunucuya doğrudan erişim kalkacak ve sunucu sorgu trafiği ortadan kalkacaktır. Tabi bunu kullanabilmek için ilk kullanımda 3 dk kadar beklemek ve yüksek kapasiteli bir RAM ihtiyacı olacaktır. Singleton bu beklemenin ve RAM ihtiyacının daha da artmasına engel olur.) İlk sorguda 3 dakikada çekilen veri sonraki sorgularda olabildiğince kısa sürede cevap dönecektir.

Çoğu durumda “static” özelliği program içinde yeterli olsa da “static” olarak belirlediğimiz sınıfın başka sınıftan “Inheritance” (kalıtım) alma özelliği olmuyor. Özellikle “inheritance” kullanacağınız zaman “Singleton Design Pattern” kullanılması önerilir.

Microsoft üzerinde: https://docs.microsoft.com/en-us/previous-versions/msp-n-p/ff650316(v=pandp.10)?redirectedfrom=MSDN

[Lea99] Lea, Doug. Concurrent Programming in Java, Second Edition. Addison-Wesley, 1999.

Yazı oluşturuldu 40

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Benzer yazılar

Aramak istediğinizi üstte yazmaya başlayın ve aramak için enter tuşuna basın. İptal için ESC tuşuna basın.

Üste dön