【PHP】半端にシングルトンなクラスを作る

  • 2020年2月20日
  • PHP

 正直アンチパターンな気がするのでこういうことができるみたいな豆知識です。コードと実行結果は次。

<?php
class HogeSingleton {
    private static $singleName;// 一度宣言されたら確定する値
    public function __construct($name = null)
    {
        // 値を持っていないならば格納される
        self::$singleName = self::$singleName ?? $name;
    }
    /**
     * @return string シングルトンとして扱っている名前
     */
    public function getMyName(){
        return self::$singleName;
    }
}

$first = new HogeSingleton('first');// 'first'で確定させる
echo $first->getMyName();
echo "\n";
$second = new HogeSingleton('second');// 'second'をいれても
echo $second->getMyName();// 'first'が返ってくる
echo "\n";
// 比較するとfalse. 別インスタンスなのはいつも通り
var_dump($first === $second);


 やっていることは静的宣言したプロパティを一度確定させたらそれっきり固定する、というやりかたです。静的プロパティをグローバル変数的に扱っているわけです。これを行うことでどのインスタンスからもプログラムのフローの途中で定まった同一のプロパティを参照できます。
 このやり方がおすすめできないのはソースコードを見るまでそれがシングルトンもどきだと気づけない点とそれに合わさったシングルトンでやるべきでないことを盛っていく危険性が高い点にあります。シングルトンもどきと気づけないのはコード末尾の比較が顕著です。本質的にシングルトンでないためハック的なこの手法を知るか知らないかでしか気づけません。このアンチパターンの怖い点はstaticなプロパティならばこの手法を取っているのではないかと思えてしまう点です。安心するには対象のプロパティが関わっているコードを読み切るしかありません(IDEの検索があるから言うほど怖くはない?手間なのは確実ですが)。
 この方法をとっていないことを示すにはconstを使うのが良いです。constならばプログラムが走り出した時点で書き換え不能ですので安心できます。

class Hoge{
    private const SINGLE_NAME = 'myname';
}

 本当にプログラムが走りだしてから定まる唯一つのものを扱うならば完全なシングルトン(常に同一インスタンスになる方法)を使った方がよいです。半端にシングルトンらしくすると謎の挙動を放ちやすくなります。

>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG