シングルトンはクラスのインスタンスを1つだけしか作れなくするもので、オブジェクト指向のデザインパターンで使われます。
それをPHPで簡単に実装するために、クラスをシングルトンに変えるtraitを作成しました。これをuseで実装するだけでシングルトンクラスになります。
シングルトンとは何か?
シングルトンは、クラスのインスタンスを1つしか作れないように制限することです。具体的にはクラスのインスタンス生成(new 演算子)を使えないようにします。
シングルトンはメモリの消費量を抑える目的や、プログラム内で共通データを保持したいときなどに使います。
そのクラスをシングルトンクラスにするtraitを作成しました。サンプルを見てみましょう。
- シングルトンは作成できるインスタンスが1つ
- メモリの消費量を抑える
- プログラムで共通データを保持する
シングルトンクラスの作成方法
<?php
namespace Test;
trait Singleton {
private static $instance;
protected function __construct() {
}
public static function get_instance() {
if ( empty( self::$instance ) ) {
self::$instance = new self();
}
return self::$instance;
}
}
5行目
$instanceは、traitを実装したシングルトンクラスのインスタンスを唯一保持するプロパティです。staticを付けます。
7行目
protectedにすることで、シングルトンクラスのインスタンスが生成できないようにします。これでシングルトンクラスはnew演算子を使えません。ここではprotectedですがprivateでもいいです。
外部からnew演算子を使えないので、インスタンスを取得するメソッド(get_instance())を用意します。get_instance()はstaticです。
唯一インスタンスを参照できるのは、get_instance()をコールしたときです。このfunctionで保持しているシングルトンクラスのインスタンスを返します。
このtraitをクラスでuseすることでシングルトンクラスにします。クラスをシングルトンクラスにする方法です。
<?php
namespace Test\Classes
use Test\Singleton
class Sample {
use Singleton;
....
}
Sample::get_instance()でシングルトンクラスのインスタンスを取得します。
シングルトンの機能をtraitに収めることで簡単にシングルトンクラスをいくつでも作成することができます。
おまけ
と思うかもしれません。
しかし、スーパークラスではシングルトンの機能が実装できません。new self は、スーパークラスのインスタンスで子クラスのインスタンスではないからです。
また、今回のtraitを実装したシングルトンクラスを継承した子クラスは、シングルトンにはなりません。理由は同じです。
今回の方法ではシングルトンクラスに必ずtraitのuseが必要です。
他にもいい方法があるような気がしているのですが、説明できるほどの内容は今のところこれがベストです。また、いい方法が思いついたら内容を更新します。