Singleton Kalıbı
Coddy'nin PHP Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 71 / 91.
Singleton Deseni, bir sınıfın uygulamanızın yaşam döngüsü boyunca yalnızca bir örneğe sahip olmasını sağlayan bir oluşturucu tasarım desenidir. Ayrıca bu örneğe küresel bir erişim noktası sağlar.
Bu desen; veritabanı bağlantısı, yapılandırma yöneticisi veya günlükçü (logger) gibi sistem genelindeki eylemleri koordine etmek için tam olarak bir nesneye ihtiyaç duyduğunuzda yararlıdır. Bunlardan birden fazla örnek oluşturmak, kaynak israfına yol açar veya tutarsız davranışlara neden olur.
PHP'de bir Singleton'ın nasıl uygulanacağı aşağıda açıklanmıştır:
<?php
class Database {
private static ?Database $instance = null;
private function __construct() {
// Özel kurucu metot, doğrudan örnek oluşturulmasını engeller
}
public static function getInstance(): Database {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
public function query(string $sql): string {
return "Executing: $sql";
}
}
$db1 = Database::getInstance();
$db2 = Database::getInstance();
echo $db1 === $db2 ? "Same instance" : "Different instances";
Çıktı:
Same instanceDesen üç temel öğeye dayanır: new anahtar kelimesinin doğrudan kullanılmasını engelleyen bir özel yapıcı, tek örneği tutan bir statik özellik ve ilk çağrıda örneği oluşturan, sonraki çağrılarda ise bu örneği döndüren bir statik metot.
Singleton'ı gerçekten kurşun geçirmez hale getirmek için, klonlamayı ve serileştirmeyi (unserialization) de engellemelisiniz:
<?php
private function __clone() {}
public function __wakeup() {
throw new Exception("Cannot unserialize singleton");
}
Görev
KolaySingleton Tasarım Kalıbını kullanarak bir yapılandırma yöneticisi (configuration manager) oluşturalım. Gerçek uygulamalarda, yapılandırma ayarları için genellikle tek bir doğruluk kaynağı istersiniz; birden fazla yapılandırma nesnesine sahip olmak, sisteminizde tutarsız davranışlara yol açabilir.
Kodunuzu iki dosya halinde düzenleyeceksiniz:
Config.php— Singleton Tasarım Kalıbını uygulayan birConfigsınıfı oluşturun. Yapılandırma yöneticiniz şunları yapmalıdır:- Ayarları özel (private) bir dizi (array) özelliğinde saklamalıdır
- Ayarlar dizisini boş olarak başlatan özel (private) bir yapıcı metoda (constructor) sahip olmalıdır
- Tek örneği döndüren statik bir
getInstance()metodu sağlamalıdır __clone()metodunu özel (private) yaparak kopyalamayı (cloning) engellemelidir- Bir ayarı saklamak için bir
set(string $key, string $value): voidmetodu içermelidir - Bir anahtarın değerini döndüren veya anahtar mevcut değilse
nulldöndüren birget(string $key): ?stringmetodu içermelidir - Tüm ayarları döndüren bir
getAll(): arraymetodu içermelidir
main.php— Config dosyasını dahil edin. İki girdi alacaksınız: bir anahtar (key) ve bir değer (value).Config örneğini alın ve anahtarı
"app_name", değeri"MyApp"olan varsayılan bir ayar atayın.Config örneğine ikinci bir referans alın (tekrar
getInstance()kullanarak) ve bunu, girdilerden gelen anahtar ve değeri kullanarak başka bir ayar atamak için kullanın.Son olarak, Singleton'ın doğru çalışıp çalışmadığını doğrulayın:
- Her iki referansın da aynı nesneyi işaret edip etmediğine bağlı olarak
"Same instance: true"veya"Same instance: false"yazdırın (karşılaştırmak için===kullanın) - Saklanan toplam ayar sayısını gösteren
"Settings count: [count]"yazdırın (getAll()sonucundacount()kullanın) - İkinci referans aracılığıyla alınan app_name ayarını gösteren
"App name: [value]"yazdırın
- Her iki referansın da aynı nesneyi işaret edip etmediğine bağlı olarak
Bu zorluk, Singleton Tasarım Kalıbının temel faydasını göstermektedir: getInstance() metodunu kaç kez çağırırsanız çağırın, her zaman aynı nesneyi alırsınız ve bu da uygulamanızın tüm bölümlerinin aynı yapılandırma durumunu paylaşmasını sağlar.
Kopya kağıdı
Singleton Deseni, bir sınıfın uygulamanızın yaşam döngüsü boyunca yalnızca bir örneğe sahip olmasını sağlar ve bu örneğe küresel bir erişim noktası sunar.
Bu desen; veritabanı bağlantıları, yapılandırma yöneticileri veya günlükçüler (loggers) gibi, birden fazla örneğin kaynak israfına yol açacağı veya tutarsız davranışlara neden olacağı nesneler için kullanışlıdır.
Temel Singleton uygulaması:
<?php
class Database {
private static ?Database $instance = null;
private function __construct() {
// Özel yapıcı metot doğrudan örneklemeyi engeller
}
public static function getInstance(): Database {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
}
$db1 = Database::getInstance();
$db2 = Database::getInstance();
echo $db1 === $db2 ? "Same instance" : "Different instances";
// Çıktı: Same instance
Temel öğeler:
- Özel yapıcı metot (Private constructor) —
newanahtar kelimesinin doğrudan kullanılmasını engeller - Statik özellik (Static property) — tek örneği tutar
- Statik metot (Static method) — ilk çağrıda örneği oluşturur ve sonraki çağrılarda bu örneği döndürür
Klonlamayı ve serileştirmeyi (unserialization) engelleme:
<?php
private function __clone() {}
public function __wakeup() {
throw new Exception("Cannot unserialize singleton");
}
Kendin dene
<?php
require_once 'Config.php';
// Girdiyi oku
$key = trim(fgets(STDIN));
$value = trim(fgets(STDIN));
// TODO: Config örneğini (instance) alın ve "app_name" değerini "MyApp" olarak ayarlayın
// TODO: getInstance() yöntemini tekrar kullanarak Config'e ikinci bir referans alın
// TODO: İkinci referansı kullanarak, girdiden gelen $key ve $value değerleriyle ayarı yapın
// TODO: Singleton'ın çalıştığını doğrulayın:
// - === karşılaştırmasına dayanarak "Same instance: true" veya "Same instance: false" yazdırın
// - Toplam ayar sayısını gösteren "Settings count: [count]" yazdırın
// - İkinci referans aracılığıyla alınan app_name değerini gösteren "App name: [value]" yazdırın
?>Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1OOP Temelleri
Harici DosyalarOOP'ye GirişSınıflar ve Nesneler$this Anahtar KelimesiMetotlarÖzelliklerYapıcı Metot (__construct)Yıkıcı Metot (__destruct)Özet - Basit Hesap Makinesi4Kalıtım
Temel Kalıtımparent:: Anahtar KelimesiMetot Geçersiz Kılmafinal Anahtar KelimesiSoyut SınıflarÖzet - Çalışan Hiyerarşisi7Kapsülleme
Public, Protected, PrivateErişim Belirleyicilere Derinlemesine BakışGetter ve Setter MetotlarıBilgi GizlemeConstructor Promotion (8.0)Özet - Öğrenci Kayıt Sistemi10İleri Düzey OOP Kavramları
Kompozisyon vs KalıtımDependency InjectionAnonim SınıflarEnum'lar (PHP 8.1)Fiber'lar (PHP 8.1)Nesne Klonlama: Derinlemesine İncelemeGenerator'lar ve Iterator'lar13Tasarı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ıRepository Kalıbı2İsim Alanları ve Autoloading
İsim Alanlarına Girişuse Anahtar KelimesiPSR-4 Autoloading StandartıComposer AutoloaderÖzet - Düzenli Proje5Arayüzler ve Sözleşmeler
Arayüzlere GirişArayüzleri UygulamaBirden Fazla Arayüz UygulamaArayüz vs Soyut SınıfArayüzler ile Tip BelirlemeÖzet - Şekil Hesaplayıcı8Sihirli Metotlar
Sihirli Metotlara Giriş__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Nesne Klonlama__serialize & __unserializeÖzet - Özel Koleksiyon3Sınıf Özellikleri
Örnek ve Statik ÖzelliklerSınıflarda SabitlerStatik Metotlar ve ÖzelliklerPrivate ve Protected ÖzelliklerReadonly Özellikler (PHP 8.1)Özet - Banka Hesabı Yöneticisi6Çok Biçimlilik
Metot Geçersiz Kılmaya Yeniden BakışArayüzler ile Çok BiçimlilikType Hinting ve Union TypesLate Static BindingÖzet - Ödeme İşlemcisi9Trait'ler
Trait'lere GirişÇoklu Trait KullanımıTrait Çakışma ÇözümüTrait'lerde Soyut MetotlarTrait'ler ve Kalıtım12Tasarı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ı15Final Meydan Okumaları
E-Öğrenme PlatformuBankacılık SistemiOyun Karakteri GeliştirmeAraç Kiralama Servisi