- - PR -
ユーティリティクラスをSingletonにしたときのデメリット
投稿者 | 投稿内容 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2005-07-04 11:03
既に書き込みがありますが、そうではありません。 インスタンスを置き換えるのは簡単ですが、クラスを置き換えるのは大変ですよ。呼び出し先の クラスが完成する前に、呼び出し側のテストをしたい場合、静的メソッドの場合はダミーの クラスを設置する必要がありますが、静的メソッドの振る舞いを変えてテストする、といった ことが簡単にはできません。 | ||||||||||||
|
投稿日時: 2005-07-04 20:13
えーっと、シングルトン自身のクラスのユニットテストじゃなくて、シングルトンを利用しているクラスのユニットテストの話をしていたと思うんですが・・・
シングルトンを利用しているクラスのユニットテストをするときにモックのシングルトンをセットしなきゃいけないでしょ? | ||||||||||||
|
投稿日時: 2005-07-04 22:18
はい、そのつもりです。私が前の投稿で示したコードでは省略しましたが、 testUseConnectionTest()メソッドには、Singletonクラスを使用する 任意のクラスの単体テストコードが入るものと思ってください。
その通りですが、前の投稿では、モックの準備はstaticメソッドの呼び出し1回だけで できることを示したつもりです。 この程度は許容範囲と考えていますが、aaさんにとっては違うということでしょうか? | ||||||||||||
|
投稿日時: 2005-07-05 01:30
そうですよ。ちなみに私はよくこんなことをします。まず、利用クラスにこんなメソッドを 作っておいて、
で、テストコードでこんなことをします。
で、テストに適した振る舞いをさせるシングルトンのインスタンスを使わせるようにする わけです。もちろん匿名内部クラスである必要はありませんが… | ||||||||||||
|
投稿日時: 2005-07-05 20:10
失礼。よく見ていませんでした。
ですが、私の美学(?)では、シングルトンなのにprotectedにすることは良しとしません。 抜け穴を作る事になるからです。 言い換えれば、privateであるはずのところをprotectedにソースを変更する事によってユニットテストを可能にしているわけで、セッターを用意して切り替えられるようにしているのとはわけが違うと思うからです。 おかしいですか? | ||||||||||||
|
投稿日時: 2005-07-05 20:22
下記の様な構成ならどうですか?
[追記] 誤解を与えたかもしれないので少し修正 [ メッセージ編集済み 編集者: ぽん 編集日時 2005-07-07 00:37 ] | ||||||||||||
|
投稿日時: 2005-07-05 21:28
その考えはよく分かります。私もテスト用に前述の設計をしたり、 テスト用のアクセサメソッドを作ったりしたときは違和感を覚えました。 最近は開き直って、「これはテストの仕方までも考慮された良い設計なのだ!」 と思うようにしています。 アクセス可能性が緩くなるという問題はありますが、テストのしやすさと秤に掛けた結果 今のスタイルを取ることが多くなりました。
申し訳ないですが、文章だけでは判断ができませんでした。 外部のクラスからアクセス可能なセッターによりSingletonの動作を切り替え可能で あるなら、アクセスが可能かどうかという観点からは Singletonクラスを継承するのと同じように思えます。 よろしければ、aaさんの普段のやり方をコードで示してもらえませんか? とても興味があります。 >ぼんさん メソッドベースDI(IoC)って奴ですね。 ただ、Singletonクラス(正確にはInterfaceインタフェースの実装クラス)に 依存する箇所が多い場合、つまり、Sample#func()のような引数にInterfaceを持つ メソッドが多い場合、Mockを注入する箇所が多くなるため、 Factory MethodパターンやDIコンテナのお世話になる必要がありそうです。 | ||||||||||||
|
投稿日時: 2005-07-06 20:59
ぽんさんへ
クラスの内部にテスト用のコードを書くのはちょっと違和感がありますね。
あはは。すごいですね。
別に立派なやり方をしているわけではないです。 普段はデータベースアクセスとかのクラスをシングルトンで実装したりして、ユニットテスト上問題だなあと常日頃思っておりました。 このスレッドで何人かの方が、シングルトンで実装すると、シングルトンを使っているクラスはユニットテストがしやすいという由の発言をされていましたので、私はそうは思わないと書いた次第です。 (シングルトンよりMathクラスにあるような単なるstaticのメソッドの方が単純にテストしやすい。) #このスレッドの最初はこういう話だったんでしたよね。 未だ試行錯誤状態なのですが、シングルトンをprotectedにしたり内部にテストコードを書いたりするよりかは、DIで実装するのがいいのではないのかなと考えております。 こんな感じです。
[ メッセージ編集済み 編集者: aa 編集日時 2005-07-06 21:03 ] |