シングルトンが邪悪な理由

このエントリーをはてなブックマークに追加
はてなブックマーク - シングルトンが邪悪な理由
LINEで送る
Pocket

最近、無駄にSingletonが使われているプログラムをメンテナンスする機会があり、非常に残念な思いをしているので、他にもSingletonが使われていることによって残念な思いをしている人を探してみました。日本語では記述が見当たりませんでしたが、英語の記事見つけました。

同じことを思っていたので、せっかくなので訳してみた。

1) Singletonはグローバルスコープからの呼び出しによく使われる。

正しい。しかし、何のためにでしょうか?singletonパターンは、あるシステム上で、明確に1つだけしか存在しない呼び出しを提供する。よって、サービス内でオブジェクトの参照を持ち回る必要がなくなる。
しかし、そのような使い方は、グローバル変数と何が違うのか?(ご存じの通り、グローバル変数って良くないよね?)

Singletonでは、インターフェイスが公開されていないから、結局、コードを読んで中身のデザインを知り、依存関係やインターフェイスを調べる必要がある。singletonを使うことによってクラスのデザインやインターフェイスが不明瞭になる。

参照を持ち回らなくて良くなる代わりに、微妙なシステムデザインになってしまう。Singletonはグローバル変数機能ではない。

システムデザインを深く考えると、ほとんどの場合、グローバル変数を使わなくて済む(=綺麗な)システムデザインを行える場合が多い。

2)Singletonはオブジェクト生成に制約を設けられる

正しい。
しかし、1クラス1責務のクラスに違反し、2つの責務を1つのクラスに課してしまっている。

クラス自身は、singletonかどうかを気にする必要は無い。
クラスはビジネス要件のみを考えるべきである。

クラスの生成方法を制限したければ、Factoryパターン化、builderパターンをを使ってオブジェクトの生成をカプセル化し、そこで制約を設ければよい。

これにより、1つのビジネス要件から責務と生成を分離出来る。

3) Singletonはクラス間の結合度を高めてしまう

テストしやすいコードにするための1つの基準として、クラス間の結合度を低くするしなければならない。
それにより、モックやスケルトンなどのダミーオブジェクトに簡単に差し替えてテストを行えるようになる。

Singletonは、生成されたオブジェクト内の結合度が高くなるので、ポリモーフィズムやダミーオブジェクトへの置き換えを難しくする。

代替手段として、1つめで指摘するように生成方法を分離することにより、結合度を下げることが出来る。

4) Singletonは状態を持ち続ける

永続性は単体テストの敵。テストを効率的に行うことは、1つ1つが独立していなければならない。そうで無ければテストが他のオブジェクトに影響されてしまう。

これは、別の場所の影響でテストが失敗してしまう可能性がある。テストは1つを明確にテスト出来ればよい。そうでなければ、バグが埋め込まれるリスクが高まります。。

静的な変数を無くすためには、テスト毎に状態変数を持たないようにすべき。Singletonは静的変数を必要としてしまう。Singletonを使わないことは、テストドリブンな開発への基本である

引用元

http://blogs.msdn.com/b/scottdensmore/archive/2004/05/25/140827.aspx

2013/1/22 追記:

It’s hard to test code that uses singletons.

http://googletesting.blogspot.jp/2008/05/tott-using-dependancy-injection-to.html

このエントリーをはてなブックマークに追加
はてなブックマーク - シングルトンが邪悪な理由
LINEで送る
Pocket

matsubokkuri

Please feel free to contact me via e-mail, twitter and facebook!

あわせて読みたい

コメントを残す