generated at
DI
dependency injection
Object間の依存関係を解決するデザインパターン
class内のinstantiateに関して依存関係逆転の原則 (DIP)をやる


関連用語の整理
Client
利用者側のObject
依存するObjectを外から受け取り、そのObjectを使用する責任を持つ
Dependencyに関しては、それのInterfaceのみを知っている
いくつかの外部のServiceを使いたい!になっている
Service
利用される側のObject
こいつがDependentされる
Dependency
DependentされるObjectのこと
つまりServiceのこと
依存Object
Iinjection
ClientにServiceを渡すこと

インジェクタ
依存オブジェクトを用意する責任を持つ
クライアントが知っているInterfaceを持つクラスを用意する


種類がある
よほどの理由がない限りはこれを使う




何が嬉しいか
結合度の低下
ClientはInterfaceのみに依存しているので、Serviceに変更があってもClientに影響しない
テストがしやすくなる
スタブやモックを準備することで、Clientを単体テストすることができる
Serviceの代わりにモックをDependentすればいい
fukabori.fm 48 35:26~で、singletonパターンがDIによって不要になった経緯などを話している



DIがない状態ではどうやっていたか
constructorの中でinstantiateしていた
ClientはServiceにがっつり依存している
ts
class Client { #service: Service; constructor() { this.#service = new Service(); } c() { this.#service.s(); } } class Service { s() { console.log("service"); } }
結合度が高い
テストがしづらい


DI使用に書き換え
ClientはServiceの抽象にのみ依存している
ts
class Client { #service: Service; constructor(service: IService) { this.#service = service; } c() { this.#service.s(); } } interface IService { s(): void; } class Service implements IService { s() { console.log("service"); } } // 利用 const service = new Service(); const client = new Client(service);



欠点
入力の数が増えすぎて、テストのパターンが増加する



用語も明確でわかりやすい