Class Test{
/**
* Örnek Değişken
*/
public $sampleVariable = NULL;
/**
* Singelton bir yapı kullanılmaktadır
* @var Test
*/
private static $_instance;
/**
* Singelton yapıyı desteklemek için private constructor yarattım içi boş.
*/
private function __construct(){
}
/**
* Singelton yapıyı destekleyen getInstance metodu
* @return Test
*/
public static function getInstance(){
if (self::$_instance == null) {
self::$_instance = new Test();
}
return self::$_instance;
}
}
Yukarıdaki kod basitçe bir singleton mimariyi gösteriyor.
Burada ben
$test = new Test()
yaratamıyorum. Çünkü constructor method’un erişilebilirliği “private” olarak belirlenmiş.
Yani ancak bu sınıfı
$test = Test::getInstance()
diyerek kullanabilirim.
Peki gelin görün ki, unuttuğumuz bir şey var.
Php’de “clone” diye bir obje kopyalama özelliği var. Nedir bu?
$a = new stdClass();
$k = $a;
dediğimizde, $a->var = 5 dediğimizde, $k da aynı şekilde değişiyor. yani bu ikisi aynı objeyi işaret ediyor.
Ancak
$a = new stdClass();
$k = clone $a;
Yazdığımızda ise, artık $k, $a nın en son halinden kopyalanıp yeni bir obje olarak oluşturuluyor.
Yani ben ilk örnekte,
$test = Test::getInstance();
yazdıktan sonra bir yerlerde
$anotherTest = clone $test;
dersem, artık yeni bir obje türetebilmiş oluyorum.
Buyrun deneyin :
$test = Test::getInstance();
$anotherTest = clone $test;
$test->sampleVariable = 5;
$anotherTest->sampleVariable = 10;
var_dump($test);
var_dump($anotherTest);
Birbirinin aynısı olmayan, aynı objenin farklı 2 instance’ını singleton mimaride de yapabilmiş oldum.
Sonuç : Demek ki, PHP de singleton mimarisi güvenilir değildir. Class’ın içerisine ancak private bir __clone metoru tanımlayınca güvenli oluyor. (@edit adil ilhan’ın yorumuna istinaden)
Yine de güzel bir design patterni olarak beğeniyorum. Ancak bilinçli kullanmanızı tavsiye ederim.