私は .NET に精通していますが、最近は Python と Ruby を使用しています。私は、Ruby で依存関係を必要とするオブジェクトに依存関係を提供する最善の方法を熟考していることに気づきました。
最初の考えでは、動的言語の寛大さ (再定義、ミックスイン、スタブなど) のために、依存関係と対話するために DI および IoC フレームワークが必要になるとは実際には考えていませんでした。しかし、その後、動的言語でDI/IoC フレームワークが必要ない理由についての答えに出会いました。提供された理由は、私にはあまりよくありません。物事を明確にする例が見られることを願っています。
私が同意しない推奨される提案:
理由 1: 依存クラスは実行時に変更できます (テストと考えてください)。
なぜ IOC コンテナーは動的言語で不要なのかでは、テストで依存クラス (注入されていない)、たとえばX
をスタブ化またはモック化できることがわかります。確かに、しかしそれには、私たちがSystem Under Test
と呼ばれるものに依存していることを知る必要がありX
ます。の代わりにSystem Under Test
突然依存する場合は、 の代わりにモックすることを忘れないでください。DI を使用する利点は、モック化された依存関係を常に渡すため、本番環境の依存関係で誤ってテストを実行することがないことです。N
X
N
X
理由 2: サブクラス化するか、テスト用にコンストラクター インジェクションを使用する
DI + Ruby、 LEGO、Play-Doh、およびプログラミングに関するすべてのお気に入りの goto リソースでは、System Under Test をサブクラス化して依存関係をモックする例を示しています。または、コンストラクター注入を使用できます。さて、B
依存しA
ます。のインスタンスB.get_dependency
を提供する whichを呼び出します。しかし、依存するものが依存する場合はどうなりますか? チェーン内の連続する各オブジェクトを呼び出す必要がありますか?B
A
A
N
X
get_dependency
理由 3: 依存関係を混在させたり、モンキーパッチを適用したりできる
Fabio は、mixins/monkeypatch だけを使用できると述べています。にmixinX
も同様N
です。しかし、問題は、依存するものがX
依存するA
場合はどうなるB
かです。チェーンのすべての依存関係にミックスインを使用するだけですか? それがどのように機能するかはわかりますが、すぐに面倒で混乱する可能性があります。
補足:多くのユーザーは、動的言語では DI フレームワークは必要ないと言っています。しかし、Angular.JS は、かなり堅実な DI システムを実装することで本当に恩恵を受けています。Angular は、動的言語である JavaScript に基づいて構築されています。このアプローチは Ruby や Python に匹敵しますか?
DI/IoC を Ruby や Python などに強制したいと言っているわけではないことに注意してください。