PHPでGoFデザインパターン 02 Singleton (その2:Clone対策)
前回PHPでGoFデザインパターン 02 Singletonの続き。
今回はオブジェクトのCloneを作成した場合のはなし。
オブジェクトをCloneした場合
元オブジェクトとクローンしてできたオブジェクトの比較をするために
乱数をセットするメソッドを追加し、呼び出して結果を見る。
Singletonクラス側
public function setRandData()
{
$this->data = mt_rand();
}
クライアント側
// クローンの作成 $instance1_clone = clone $instance1; // それぞれのオブジェクトを操作する echo "=====setRandData=====\r\n"; $instance1->setRandData(); $instance1_clone->setRandData(); // 結果を比較 echo "instance1 :[" . $instance1->getData() . "]\r\n"; echo "instance1_clone:[" . $instance1_clone->getData() . "]\r\n";
結果
つまり、Singletonの特徴である
そのクラスのインスタンスが1つしか生成されないことを保証することができる。 ロケールやLook&Feelなど、絶対にアプリケーション全体で統一しなければならない仕組みの実装に使用される。
(Wikipediaより引用)
が実現できていないことになる。
Clone対策
http://php.net/manual/ja/language.oop5.cloning.phpによると
オブジェクトのコピーは、clone キーワード (これは、そのオブジェクトの __clone() メソッドがある場合にこれをコールします)により作成されます。 オブジェクトの __clone() メソッドを直接コールすることはできません。
__clone()メソッドを追加し、その内で例外を発生させてみる。
SingletonSample.php
public final function __clone() { throw new RuntimeException ('Clone is not allowed class:'. get_class($this)); }