Python ile Singleton Patern’i

Pratikte herhangi bir sınıf türünde birçok kez nesne örneği (object instance) yaratmak istenebilir. Bu işlem normal yollarla yapıldığında yaratılan her bir nesne örneği için bellekte farklı bir yer tahsis edilecek ve nesnenin veri elemanlarında taşıyacağı değerler yani durum bilgisi bu alanlara yerleştirilecektir. Ancak bazı durumlarda ve bazı nesneler için kaç kez nesne örneği yaratılmak istenilirse istenilsin ilk seferinde yapılan yaratma işleminden sonra -yaratma işlemi tekrar edilse bile- yeni bir nesne daha yaratılmaksızın hep bu ilk nesne örneğinin kullanılmasına ihtiyaç duyulabilir. Başka bir deyişle söz konusu sınıf nesnesinin sadece bir kereliğine yaratılıp, daha sonra sürekli olarak kendisinin kullanılması isteniyor olabilir. İşte bu ihtiyacı karşılayan tasarım çözümünün ismi; Singleton patern’idir.

Singleton Patern’inin Uygulanmasıyla İlgili Esaslar

  1. Bu paternin uygulandığı sınıflarda, kendi türünde private ve static bir nesne olmalıdır. Statik olmasının sebebi; taşıyacağı adresin nesneden bağımsız ve sabit şekilde kullanılması ihtiyacıdır. (Örnekteki ismi; m_smp’dir)
  2. Söz konusu sınıfın türündeki nesnenin yaratılışı sadece bir kez yapılmak istendiği için sınıfın init fonksiyonu (initializer’ı) private tanımlanarak kullanıcı taraftan gizlenmelidir. Böylece sınıfı kullanacak olan programcı init() fonksiyonunu doğrudan çağıramaz hale gelir.
  3. init() fonksiyonunun bir anlamda yerini alacak olan, bir class üye fonksiyon (singleton nesne yaratıcı fonksiyon) olmalıdır. Bu fonksiyon 1. maddede anlatılmış olan statik nesnenin taşıyacağı adresi geriye döndürecek şekilde yazılmalıdır. Ancak kuşkusuz bu değer geriye döndürülmeden önce nesne için tahsisat yapılmış olmalıdır ki tahsisatın başlangıç adresi bu nesneye atansın ve geriye döndürülebilsin. Bu işlemler söz konusu fonksiyon içerisinde gerçekleştirilir. (Örnekteki ismi; CreateObject()’tir.)

class Sample:

    m_Smp = None

    class __Sample:

        def __init__(self):

            self.val = None

            print(“Sample nesnesi yaratıldı”)

    #CreateObject

    def __new__(cls):

        if not Sample.m_Smp:

            Sample.m_Smp = Sample.__Sample()

        return Sample.m_Smp

    #GetData

    def __getattr__(self, name):

        return getattr(self.m_Smp, name)

    #SetData

    def __setattr__(self, name):

        return setattr(self.m_Smp, name)

obj1 = Sample()

obj2 = Sample()

obj3 = Sample()

obj1.val = 7877

print(“obj1-Data: ” + str(obj1.val))

print(“obj2-Data: ” + str(obj2.val))

print(“obj3-Data: ” + str(obj3.val))

print(“———–“)

obj2.val = 1999

print(“obj1-Data: ” + str(obj1.val))

print(“obj2-Data: ” + str(obj2.val))

print(“obj3-Data: ” + str(obj3.val))

Bu durum şöyle yorumlanabilir; 7877 değeri obj1 ile set edildikten sonra, diğer nesneler de aynı veriyi referanse ettiklerinden dolayı, veri alındığında hep aynı değerlere ulaşılmaktadır. Keza obj2 ile 1999 değeri set edilip, veri tekrar alındığında bu kez üç sefer de 1999 değerine ulaşılmaktadır.

Reklamlar