【70】シングルトンパターンの誘惑に負けない

サム・サーリスト(Sam Saariste)

 シングルトン(Singleton)パターンは多くの問題の解決に役立つパターンです。このパターンでは、クラスのインスタンスは必ず 1 つしか生成されません。そのインスタンスは使用前に必ず初期化されます。そしてシングルトンをグローバルアクセスポイントとすることで、設計をシンプルにできます。こう書いていくと良いことずくめのようですが、この「古典的な」デザインパターンに何か短所はあるのでしょうか。

 実はたくさんあります。それはよく考えてみるとわかります。確かにシングルトンパターンは魅力的なのですが、私の経験では、このパターンには利点よりも弊害の方が多いと言えます。まずテストの妨げになります。そして保守性の点でも不利です。残念ながらその事実は広く知られているとは言えないため、多くのプログラマを惹きつけているのです。つい使いたい誘惑にかられますが、その誘惑に抵抗しなくてはなりません。

 シングルトンパターンに具体的にどんな問題があるかを次にまとめておきます。

 シングルトンは、クリーンアップに関しても問題を起こしやすいと言えます。

 シングルトンの欠点の中には、ある種のメカニズムを付加することで克服できるものもあります。しかし、それによってコードはどうしても複雑になってしまいます。シングルトンパターンさえ選択しなければ、そういう心配はいらないのです。

 シングルトンパターンは、必要なインスタンスが絶対に 1 つだけと確信できるクラス以外では使うべきではないでしょう。そして、シングルトンをグローバルアクセスポイントとすることも避けるべきです。グローバルアクセスポイントになってどこからアクセスされるかわからないというのは良くないのです。シングルトンへの直接のアクセスは、あらかじめ定めておいたごく少数の箇所からのみ行うようにします。そして他のコードからは、インタフェースを通じてアクセスするのです。他のコードは、そのインタフェースを実装するのがシングルトンなのか、あるいは他の種類のクラスなのか、ということには関知しません。つまりシングルトンに依存しないのです。それにより、ユニットテストの妨げとなる依存関係も生じずに済み、保守性も向上します。今後、シングルトンの実装やシングルトンへのアクセスを検討する時があれば、いったん立ち止まって、ここに書いたようなことをじっくり考えてみてください。