依存性注入 — 引数で受け取るということ
一言でいうと
依存性の注入は難しい概念ではなく、引数で受け取ることです。グローバルを直接 参照する代わりに外から渡せば、テストのときに別のものを渡せます。
なぜ必要なのか: テストのためではありません
DIを「テストのために使うもの」として学ぶと、目的がずれます。本当の理由は、 差し替えられる場所をコードに示しておくことです。
ストアをPostgreSQLからRedisキャッシュの手前へ移すとします。ハンドラーが
db.query(...)を直接呼んでいると、ハンドラーをすべて直す必要があります。ストアを
引数で受け取っていれば、渡す側だけが変わります。テストのしやすさは、その性質の副産物です。
手で作るとこうなります
export function createApp({ store }) {
return async function handle(req) { /* store 를 쓴다 */ };
}
フレームワークがしているのは、この{ store }を自動で探して渡すことだけです。
NestのproviderやSpringのBeanが、その自動化です。自動化が隠しているものが何かを
知らないと、注入されないときに見る場所もわかりません。
現場では
面接で「なぜDIを使うのですか」と聞かれると、たいてい「テストしやすいからです」と 答えます。間違いではありませんが、半分です。依存の向きを逆にして、上位モジュールが 下位モジュールの実装に縛られないようにすることが目的で、テストのしやすさはその結果です。
そして実務でDIが崩れる場所は、いつも同じです。グローバルなシングルトンを「楽だから」と 直接importした瞬間です。そのときから、そのモジュールは差し替えられなくなります。