私は依存性注入を使用するコードを作成しようとしています。これは、モッキングを許可し、よりクリーンで明示的な設計を行うためです。
よくあることだと思っていた特定の問題に直面することがよくありますが、それを克服するのに役立つものをネット上でまだ見つけていません。
問題は、オブジェクト A が B に依存し、B が C に依存し、C が D に依存するというように、多くのリンクを持つチェーン内にある場合です。
ここで依存性注入を実行するには、A はそのコンストラクターで B、C、D などを要求する必要があるようです (または、依存するインスタンスを作成するオブジェクトの場合は BFactory、CFactory など)。議論のために、依存関係はオプションではなく、特定のメソッドに制限されているため、セッター注入またはメソッドパラメーター注入は不適切であると想定しています。
これは、依存オブジェクトの長いチェーンがアンチパターンであることを示唆しています。抽象的な意味では、矢じりのアンチパターンと共通点があります。依存オブジェクトの長いチェーンは、矢印の形をしたシーケンス図を形成します。
おそらく、私はこの慣行を避け、「Zen of Python」の「入れ子よりもフラットの方が良い」というアドバイスに従うべきです。これは、メイン プログラムが 2 つまたは 3 つのオブジェクトを作成し、それらが共同して結果を生成し、それがメイン プログラムに返される設計を示唆しています。次に、別の 2 つまたは 3 つのオブジェクトを作成して、作業の次の段階を実行します。
この種のコードは、依存関係の注入を容易にするだけでなく、理解しやすく、デバッグしやすいと感じています。しかし、Tell Don't Ask の原則に反しているようで、メイン プログラムが太りすぎます。私は、main が非常に小さくて明白であるため、単体テストを必要としないという考えが気に入っています。そして、Tell Don't Ask は、すべてが A で始まり A で終わる場合、それは A の責任であると私に言います。A が請求対象の顧客であり、請求プロセスを開始するために必要なデータと、最後に請求書を送信する必要がある電子メール アドレスを顧客が所有しているとします。次に、メインに大量の請求書と電子メールアドレスを渡して責任をメインに戻すのではなく、A が自分で作業を行う必要があるようです (メインは Customer.billYourself() を呼び出すだけでよい)。
では、DI を容易にするために依存関係の連鎖を避けるべきでしょうか、それとも、Tell Don't Ask のために依存関係を受け入れる必要があるのでしょうか?