初期化するいくつかのオブジェクトの異なる実装を使用する必要がないコンストラクターを考えると、DIを使用することは依然として実用的ですか?結局のところ、まだ単体テストが必要な場合があります。
問題のクラスは、コンストラクター内の他のいくつかのクラスを初期化し、使用するクラスは非常に具体的です。別の実装を使用することはありません。インターフェイスにプログラムしようとするのを避けることは正当化されますか?
初期化するいくつかのオブジェクトの異なる実装を使用する必要がないコンストラクターを考えると、DIを使用することは依然として実用的ですか?結局のところ、まだ単体テストが必要な場合があります。
問題のクラスは、コンストラクター内の他のいくつかのクラスを初期化し、使用するクラスは非常に具体的です。別の実装を使用することはありません。インターフェイスにプログラムしようとするのを避けることは正当化されますか?
回答:
それは、「決して、これまで」が正しいことをどの程度確信しているかによって異なります(アプリが使用される間)。
一般に:
インターフェイスにプログラムしようとするのを避けることは正当化されますか?
インターフェイスに対するコーディングの利点は明らかですが、それを行わないことで何が正確に得られるかを自問する必要があります。
次の質問は、問題のクラスが実装を選択する責任があるかどうかです。その場合もそうでない場合もあるので、それに応じて行動する必要があります。
最終的に、間抜けな制約が突然発生する可能性が常にあります。同じコードを同時に実行したい場合があり、実装をインジェクトする可能性が同期に役立つ場合があります。または、アプリをプロファイリングした後、単純なインスタンス化とは異なる割り当て戦略が必要な場合があります。または、分野横断的な懸念が生じ、AOPサポートが手元にありません。知るか?
YAGNIは、コードを記述するとき、余分なものを追加しないことが重要であることを提案します。プログラマーが気付かないうちにコードに追加する傾向があるものの1つは、不必要な仮定です。「この方法は便利かもしれない」や「これは決して変わらない」など。どちらもデザインに混乱をもたらします。
さまざまなパラメーターに依存しますが、DIを使用したい理由がいくつかあります。
要するに、その場合はおそらくDIなしで生きることができますが、DIを使用するとコードがきれいになる可能性があります。
> Dependency Injection worth it **outside** of UnitTesting?
> Are we justified in avoiding trying to program to an interface?
この質問に対する多くの答えは、ユニットテストを行いたくない場合、YAGNIとして「..が必要な可能性がある」として議論することができます。
ユニットテストのほかに、インターフェイスにプログラムする必要がある理由を尋ねる場合
はい、コントロールの反転が必要な場合は、UnitTesting 以外の価値があるDependency Injection です。たとえば、あるモジュールの実装に、そのレイヤーでアクセスできない他のモジュールが必要な場合。
例:モジュールがある場合gui
=> businesslayer
=> driver
=> common
。
このシナリオでbusinesslayer
は、使用できますdriver
が使用driver
できませんbusinesslayer
。
よりdriver
高いレベルの機能が必要な場合は、この機能businesslayer
を実装して、インターフェイスをcommon
レイヤーに実装できます。
レイヤーdriver
内のインターフェースのみを知る必要がありますcommon
。
はい、そうです。まず、単体テストツールを中心にコードを設計する理由として単体テストを忘れてください。人為的な制約に合わせてコード設計を曲げることは決して良い考えではありません。ツールでこれを行う必要がある場合は、より優れたツール(モックオブジェクトを作成するためのより多くのオプションを許可するMicrosoft Fakes / Molesなど)を入手してください。
たとえば、テストツールがプライベートメソッドで機能しないという理由だけで、クラスをパブリックメソッドのみに分割しますか?(私は、プライベートメソッドをテストする必要がないふりをするのが一般的な知恵であることを知っていますが、これはプライベートツールをテストする必要がないという真の反応ではなく、現在のツールでテストするのが難しいことへの反応だと思います)。、
全体として、それはあなたがどんな種類のTDDerであるか- ファウラーがそれらを説明する「モック主義者」であり、使用するツールに合わせてコードを変更する必要があるのに対し、「古典的な」テスターはより自然に統合されたテストを作成します(つまり、各メソッドではなくユニットとしてクラスをテストします)、特に具象クラスをモックできるツールを使用する場合は、インターフェースの必要性が少なくなります。
依存性注入はまたあなたのオブジェクトがあること、それが明確になりHASの依存関係を。
他の誰かが(コンストラクターを見ずに)オブジェクトを単純に使用すると、サービスや接続などをセットアップする必要があることに気付くでしょう。コンストラクターに渡す必要がないため、明らかではありませんでした。 。依存関係を渡すと、必要なものがより明確になります。
また、クラスがSRPに違反している可能性があるという事実を潜在的に隠しています。多くの依存関係(3つ以上)を渡す場合は、クラスの処理が多すぎる可能性があるため、リファクタリングする必要があります。ただし、コンストラクターで作成する場合、このコードの匂いは隠されます。
私はここの両方のキャンプに同意します、そして、問題は私の意見で議論のためにまだ開いています。YAGNIは、推測に合うようにコードを変更することはしないよう要求しています。ここでは、単体テストは問題ではありません。依存関係は決して変化しないと固く信じているからです。しかし、もし私が最初から意図したとおりに単体テストをしていたなら、とにかくこの点に到達することはなかったでしょう。私は最終的にDIへの道をスリム化したので。
私のシナリオの別の代替案を具体的に提供させてください
ファクトリパターンを使用すると、1つの場所で依存関係をローカライズできます。テスト時には、コンテキストに基づいて実装を変更できますが、それで十分です。これは、いくつかのクラス構成を抽象化する利点があるため、YAGNIには反しません。