本記事に掲載したサンプルコードは、https://github.com/ryo-utsunomiya/design_patternでも公開中です。
Singletonとは
Singletonは、インスタンスが1個しか存在しないことを保証するパターンです。
<?php
namespace my;
class Singleton
{
/**
* @var Singleton
*/
private static $singleton;
private function __construct() { }
/**
* @return Singleton
*/
public static function getInstance()
{
if (is_null(self::$singleton)) {
self::$singleton = new self();
echo 'Instance is generated.', PHP_EOL;
}
return self::$singleton;
}
}
Singletonでは、newによるインスタンスの生成を禁止するため、コンストラクタをprivateにするのが一般的です。その代わり、インスタンスの生成・取得を担うメソッドを用意します。
上記サンプルコードのSingletonクラスでは、getInstanceメソッドがインスタンスの生成・取得を担っています。Singletonクラスのインスタンスがself::$singletonにセットされていればそれを返し、セットされていない場合はインスタンスを生成して返します。
このクラスを利用したコードは以下のようになります。
<?php
namespace my;
require_once __DIR__ . '/../autoload.php';
echo 'Start.', PHP_EOL;
$obj1 = Singleton::getInstance();
$obj2 = Singleton::getInstance();
printf("obj1 is %s.n", get_class($obj1));
printf("obj2 is %s.n", get_class($obj2));
if ($obj1 === $obj2) {
echo '$obj1 and $obj2 is same instance.', PHP_EOL;
} else {
echo '$obj1 and $obj2 is different instance.', PHP_EOL;
}
echo 'End.', PHP_EOL;
$obj1と$obj2は別の変数ですが、全く同一のインスタンスを参照しています。
なお、PHPではオブジェクトの比較には注意が必要です。
比較演算子(==)を使用する際、 オブジェクト変数は、単純に比較されます。つまり、 二つのオブジェクトのインスタンスは、 同じ属性と値を有し、同じクラスのインスタンスである場合に、 等しいとされます。
一致演算子(===)を使用する場合、 オブジェクト変数は、同じクラスの同じインスタンスを参照する場合のみ、 等しいとされます。
http://php.net/manual/ja/language.oop5.object-comparison.php
ここでは、同じインスタンスであることを確認するため「===」を使用しています。