PEAR::Log::singleton() -- Singleton Method
GoFデザインパターンのうちのひとつであるシングルトンパターンはこのPearLogにも実装されています。
ただし、1クラス1インスタンスではなく、`全く同じ引数群`につき1インスタンスです。ここがこのSingletonの使い勝手の悪いところです。
引数はfactory()と同じになるので省略します。
何をさておいて、まずは実際の実装部分を見てもらったほうが話が早いと思いますので、そこから。
function &singleton($handler, $name = '', $ident = '', $conf = array(), $level = PEAR_LOG_DEBUG) { static $instances; if (!isset($instances)) $instances = array(); $signature = serialize(array($handler, $name, $ident, $conf, $level)); if (!isset($instances[$signature])) { $instances[$signature] = &Log::factory($handler, $name, $ident, $conf, $level); } return $instances[$signature]; }
staticである$instances配列に引数配列のシリアライズをキーに使い、そのキーがない場合にのみ新たにその引数によるインスタンスを生成する。そして、インスタンスを返すという手順を踏みます。実に単純です。
単純ですが、$confや$levelまでも存在基準の対象となってしまう*1ので、Log::singletonを呼び出しごとにべた書きしていると、実は別のインスタンスが飛び出してくるというミスをよく犯してしまいます。
そのため、個人的にはあまりSingletonの恩恵を感じたことがないというのが正直なところ。singleton()利用の際には結局PearLogファクトリクラスを作ったり、設定ファイルベース(DI等)の生成などで対応してしまうことになってしまうのです。
けれど、factory()で生成してからそれをあちらこちらへ持ちまわさなければいけないというのも面倒な作業になるわけで、そこは適宜使い分けでしょう。
*1:考えればそういう実装にして当然のことですけど