Singleton の目的
- 指定したクラスのインスタンスが絶対に1個しか存在しないことを保証したい
- インスタンスが1個しか存在しないことをプログラム上で表現したい
また、
たとえば、システムの設定を表現するクラスや、システム全体で一度読み込んだデータをキャッシュしておくクラスで利用する。
Singleton の実装に関して
Singleton クラスのコンストラクタは private にする。
Singleton クラス外からコンストラクタを呼ぶことを防ぐため。
下記の方法でインスタンス生成できないようにする
- 自身を外部から new する
- 外部から clone する
- 派生クラスを new する(派生クラスを作ることができないようにする)
Singleton の実装例
<?php
// final で派生クラスを作ることができないようにする
final class Singleton
{
private static $instance;
private $id;
private function __construct()
{
$this->id = time();
}
private function __clone()
{
}
public static function getInstance()
{
if (is_null(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
public function getId()
{
return $this->id;
}
}
$ins1 = Singleton::getInstance();
sleep(3);
$ins2 = Singleton::getInstance();
print($ins1 === $ins2);
print "\n";
print($ins1->getId() === $ins1->getId());
print "\n";
出力結果
1
1
エラーパターンの確認
- 自身を外部から new する
$ins0 = new Singleton();
// Fatal error: Call to private Singleton::__construct() が発生
- 外部から clone する
$clone_class = clone $ins1;
// Fatal error: Call to private Singleton::__clone() が発生
- 派生クラスを new する(派生クラスを作ることができないようにする)
class ChildSingleton extends Singleton
{
public function __construct()
{
}
}
$ins3 = new ChildSingleton();
// Fatal error: Class ChildSingleton may not inherit from final class (Singleton) が発生