コラム

Singleton シングルトンパターンでインスタンスを一つに限定しよう

※この記事の注意事項
・できるだけ初心者の方が理解しやすいように、細かい説明は省略しております。
・最後まで読み進められるように、多少ユーモアを交えて表現していることがあります。

========================================

Singleton シングルトンパターンは、クラスのインスタンスを一つしか作りたくない場合に使用します。

でも、口頭の伝達で「このクラスはインスタンス一つだけにしてください」と言っても、人間が行うことにミスは付き物です。
ですので、構造的に一つしか作れないようにします。

なぜインスタンスを一つだけにしたいかというと、newしてインスタンスを作ると、メモリ消費量が増えるんですね。
インスタンスが一つあればよい状態であれば、一つ作ったものをみんなで使いまわせばいいという考え方ですね。

メモリ使用量だけではなく、唯一であって欲しい場合重複して欲しくない場合なども当てはまりますね。

シングルトンパターンは以下のように実装します。

class SingletonClass
{
    private static $instance;

    private function __construct()
    {
        # code...
    }

    public static function getInstance()
    {
        if (!isset(self::$instance)) {
            self::$instance = new SingletonClass();
        }

        return self::$instance;
    }

    public final function __clone()
    {
        throw new RuntimeException('Cloneは使用できません');
    }

    public function getName()
    {
        echo '名前を出力!';
    }
}

__construct コンストラクタがプライベートになっているのでnewができないようになっています。newさせない代わりに、getInstanceでインスタンスを生成しています。生成したインスタンスは自身の中に保持しています。プライベートな変数ですので、外部からの直接アクセスはできませんpublicなメソッド経由でアクセスします。

自身の中にインスタンスがない場合に限りインスタンスを生成する仕組みなので、一つしかインスタンスを生成しない仕組みになっています。

__cloneという、インスタンスをクローンできるメソッドがあるので、__clone時にはエラーが出るように設定しています。

以下で2回インスタンスの呼び出し(なければ生成)をしていますが、呼び出されたインスタンスは同じものであることがわかります。
newができないこと、cloneができないことも確認しています。

$instance1 = SingletonClass::getInstance();

$instance2 = SingletonClass::getInstance();

if ($instance1 === $instance2) {
    echo '2つのクラスは同一です';
} else {
    echo '異なるクラスが生成されました';
}

//メソッド呼び出しテスト
$instance1->getName();

//newができないことを確認
$instance = new SingletonClass(); //Fatal error

//クローンができないことを確認
$instance_clone = clone $instance1; //Fatal error

========================================

▼PHPのオブジェクト指向とデザインパターン記事一覧

関連記事

コメント

  • トラックバックは利用できません。

  • コメント (0)

  1. この記事へのコメントはありません。