Singleton Kalıbı
Coddy'nin Python Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 45 / 64.
Singleton deseni, bir sınıfın yalnızca bir örneğe sahip olmasını sağlar ve ona küresel bir erişim noktası sunar. Bu, veritabanı bağlantıları veya yapılandırma ayarları gibi kaynaklar için kullanışlıdır.
İşte temel bir Singleton uygulaması:
class Singleton:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance__new__ yöntemi nesne oluşturmayı kontrol eder. Yeni bir tane oluşturmadan önce bir örneğin zaten var olup olmadığını kontrol eder.
Singleton sınıfından iki örnek oluşturun:
singleton1 = Singleton()
singleton2 = Singleton()Her iki değişkenin de aynı nesneye başvurup başvurmadığını kontrol edin:
print(singleton1 is singleton2) # True
print(id(singleton1)) # Aynı bellek adresi
print(id(singleton2)) # Aynı bellek adresiİşte bir veritabanı bağlantısı içeren daha pratik bir örnek:
class DatabaseConnection:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
cls._instance.connection = "Connected to MySQL database"
print("Creating new database connection")
return cls._instance
def query(self, sql):
return f"Executing: {sql}"
# İlk erişim bağlantıyı oluşturur
db1 = DatabaseConnection()
print(db1.connection)
# İkinci erişim aynı bağlantıyı yeniden kullanır
db2 = DatabaseConnection()
print(db2.connection)
print(db1.query("SELECT * FROM users"))
print(db1 is db2)Singleton kullanarak bir yapılandırma yöneticisi oluşturun:
class Config:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
cls._instance.settings = {}
return cls._instance
def set_setting(self, key, value):
self.settings[key] = value
def get_setting(self, key):
return self.settings.get(key)
config1 = Config()
config1.set_setting("debug", True)
config2 = Config()
print(config2.get_setting("debug")) # True - aynı ayarlarÇıktı:
True
140234567890123
140234567890123
Creating new database connection
Connected to MySQL database
Connected to MySQL database
Executing: SELECT * FROM users
True
TrueÖnemli Nokta: Singleton deseni, nesne oluşturmayı kontrol etmek için __new__ metodunu kullanarak yalnızca bir örneğin var olmasını sağlar. Bunu, veritabanı bağlantıları, günlükçüler veya yapılandırma yöneticileri gibi uygulamanız boyunca yalnızca bir kopyası olması gereken kaynaklar için kullanın. Bir Singleton'ı işaret eden tüm değişkenlerin bellekteki aynı nesneye başvurduğunu unutmayın.
Görev
KolayBu meydan okumada, bir veritabanı bağlantı sınıfı için Singleton tasarım desenini uygulayacaksınız.
- TODO yorumlarını takip ederek Singleton desenini uygulamak için
databaseconnection.pydosyasını düzenleyin driver.pydosyası kapsamlı test senaryoları içerir ve değiştirilmemelidir
Kopya kağıdı
Singleton deseni, bir sınıfın yalnızca bir örneği olmasını sağlar ve ona küresel bir erişim noktası sunar.
__new__ kullanarak temel Singleton uygulaması:
class Singleton:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance__new__ metodu, yeni bir tane oluşturmadan önce bir örneğin zaten var olup olmadığını kontrol ederek nesne oluşturmayı denetler.
Singleton örneklerini test etme:
singleton1 = Singleton()
singleton2 = Singleton()
print(singleton1 is singleton2) # True - aynı nesneVeritabanı bağlantısı ile pratik örnek:
class DatabaseConnection:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
cls._instance.connection = "Connected to MySQL database"
return cls._instance
def query(self, sql):
return f"Executing: {sql}"Yapılandırma yöneticisi örneği:
class Config:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
cls._instance.settings = {}
return cls._instance
def set_setting(self, key, value):
self.settings[key] = value
def get_setting(self, key):
return self.settings.get(key)Veritabanı bağlantıları, günlükçüler veya yapılandırma yöneticileri gibi uygulamanız boyunca yalnızca bir kopyası olması gereken kaynaklar için Singleton kullanın.
Kendin dene
from databaseconnection import DatabaseConnection
# Kapsamlı test senaryosu işleyicisi
test_case = input()
if test_case == "identity_check":
db1 = DatabaseConnection()
db2 = DatabaseConnection()
print(db1 is db2) # True yazdırmalı
elif test_case == "connect_state":
db = DatabaseConnection()
print(f"Initial connected state: {db.connected}") # False yazdırmalı
db.connect()
print(f"After connect: {db.connected}") # True yazdırmalı
elif test_case == "disconnect_state":
db = DatabaseConnection()
db.connect()
db.disconnect()
print(f"After disconnect: {db.connected}") # False yazdırmalı
elif test_case == "multiple_instances_same_state":
db1 = DatabaseConnection()
db1.connect()
db2 = DatabaseConnection()
print(f"db2 connected state: {db2.connected}") # True yazdırmalı
elif test_case == "host_value":
db = DatabaseConnection()
print(f"Default host: {db.host}") # "localhost" yazdırmalı
db.host = "new-server"
db2 = DatabaseConnection()
print(f"New instance host: {db2.host}") # "new-server" yazdırmalı
elif test_case == "init_once":
db1 = DatabaseConnection()
db1.host = "custom-host"
db2 = DatabaseConnection()
print(f"Both instances have same host: {db1.host == db2.host}") # True yazdırmalı
print(f"Host value: {db1.host}") # "custom-host" yazdırmalı
elif test_case == "connect_message":
db = DatabaseConnection()
db.connect() # "Connected to database at localhost" yazdırmalı
elif test_case == "disconnect_message":
db = DatabaseConnection()
db.connect()
db.disconnect() # "Disconnected from database" yazdırmalı
elif test_case == "attribute_modification":
db1 = DatabaseConnection()
db1.port = 3306
db2 = DatabaseConnection()
print(f"db2 has port attribute: {hasattr(db2, 'port')}") # True yazdırmalı
print(f"db2 port value: {db2.port}") # 3306 yazdırmalı
elif test_case == "reset_connection":
db1 = DatabaseConnection()
db1.connect()
print(f"Connected state: {db1.connected}") # True yazdırmalı
db2 = DatabaseConnection()
print(f"New instance connected state: {db2.connected}") # True yazdırmalı
db2.disconnect()
db3 = DatabaseConnection()
print(f"After disconnect, new instance state: {db3.connected}") # False yazdırmalı
elif test_case == "multiple_connects":
db = DatabaseConnection()
db.connect()
db.connect()
db.connect()
print(f"Connected state after multiple connects: {db.connected}") # True yazdırmalı
db.disconnect()
print(f"Connected state after disconnect: {db.connected}") # False yazdırmalı
elif test_case == "host_change_affects_message":
db = DatabaseConnection()
db.host = "custom-server"
db.connect() # Hala "Connected to database at localhost" yazdıracaktır
# connect metodu, host özniteliğini kullanmayan sabit kodlanmış bir mesaja sahiptir
print("Message still shows localhost: True")Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Object Oriented Programming bölümündeki tüm dersler
1OOP Temelleri
Harici DosyalarOOP'ye GirişSınıflar ve Nesnelerself ParametresiMetotlarÖzniteliklerYapıcı Metot (__init__)Özet - Basit Hesap Makinesi4Kalıtım
Temel Kalıtımsuper() FonksiyonuMetot Geçersiz KılmaÇoklu KalıtımMetot Çözümleme SırasıÖzet - Çalışan Hiyerarşisi7Özel Metotlar
Sihirli Metotlara GirişOperatör Aşırı YüklemeKapsayıcı Sihirli MetotlarıÖzet - Özel Liste10Tasarım Kalıpları Bölüm 1
Tasarım kalıplarına girişSingleton KalıbıFactory KalıbıObserver KalıbıStrategy Kalıbı13Final Meydan Okumaları
E-öğrenme PlatformuBankacılık SistemiOyun Karakteri GeliştirmeAraç Kiralama Servisi5Çok Biçimlilik (Polymorphism)
Metot Geçersiz Kılmaya Yeniden BakışDuck TypingSoyut Sınıflar ve MetotlarArayüz TasarımıÖzet - Şekil Hesaplayıcı8İleri Düzey OOP Kavramları
Kompozisyon ve KalıtımMixinsStatik ve Sınıf MetotlarıSınıf DekoratörleriBağlam Yöneticileri11Tasarım Kalıpları Bölüm 2
Komut KalıbıAdaptör KalıbıDekoratör KalıbıŞablon Metot KalıbıDurum KalıbıKompozit Kalıbı