Dependency Injectionって「依存性の注入」じゃないの?
やっていることは、 依存しているオブジェクトを注入するようにする なので、「依存オブジェクトの注入」の方が訳としてただしいのでは? という議論がある
あと、自分が読んでいるオブジェクト指向設計実践ガイドでも「依存オブジェクトの注入」が採用されているので、こちらを使う

オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方
- 作者: Sandi Metz,?山泰基
- 出版社/メーカー: 技術評論社
- 発売日: 2016/09/02
- メディア: 大型本
- この商品を含むブログ (4件) を見る
依存オブジェクトの注入 ってどういう時の使うの?
依存性が高いオブジェクトを内包している時。そのオブジェクトを外部から注入するように修正する
具体的にはこんなコード(オブジェクト指向設計実践ガイドより)
class Gear attr_reader :chainring, :cog, :rim, :tire def initialize(chainring, cog, rim, tire) @chainring = chainring @cog = cog @rim = rim @tire = tire end def gear_inches ratio * Wheel.new(rim, tire).diameter end # ... end Gear.new(52, 11, 26, 1.5).gear_inches
このコードのどこが問題なの?
ギアのインチを計算する Gear#gear_inches
が、Wheel
に 依存した状態 である
結果的に以下のような問題が発生する
- 変更時のコストが高い
- 例えば
Wheel.new
のためだけに、rim
とtire
がGear#initialize
に渡されている。そのため、Wheel.new
の引数が変わったら、Gear
は大幅に変更が必要になる - そもそもここに
Wheel
があることを知らなければ、修正が必要なことにも気が付けない
- 例えば
- 再利用性が低い
Wheel
以外のオブジェクトからギアを計算したい時、別のメソッドが必要
- テスト実装のコストが高い
- テストを書く時に、
Wheel
オブジェクトのことを考慮する必要がある
- テストを書く時に、
じゃあどんなふうに直したら良いの?
こんなふうに、Gear
に対して外部から、diameter
を呼べるオブジェクトを注入してあげれば良い
class Gear attr_reader :chainring, :cog, :wheel def initialize(chainring, cog, wheel) @chainring = chainring @cog = cog @wheel = wheel end def gear_inches ratio * wheel.diameter end # ... end Gear.new(52, 11, Wheel.new(26, 1.5)).gear_inches
こうすれば、 Gear
は、Wheel
に依存しなくなり、
wheel
については #diameter
さえ実行できればどんなオブジェクトでも良くなる → ダックタイピング
なので、Wheel
が変更されてね影響は少なくなるし、テストするときも簡単な mock を作れば良いだけになる
蛇足
むしろ、「依存性オブジェクトの排除」とか言ったほうが意味が通じそう、という話を会社のQiita::Teamでした