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を持つクラスを用意する
種類がある
Constructor Injection
よほどの理由がない限りはこれを使う
フィールドインジェクション
セッターインジェクション
メソッドインジェクション
何が嬉しいか
結合度の低下
ClientはInterfaceのみに依存しているので、Serviceに変更があってもClientに影響しない
テストがしやすくなる
スタブやモックを準備することで、Clientを単体テストすることができる
Serviceの代わりにモックをDependentすればいい
fukabori.fm 48 35:26~で、singletonパターンがDIによって不要になった経緯などを話している
DIがない状態ではどうやっていたか
constructorの中でinstantiateしていた
ClientはServiceにがっつり依存している
code:ts
class Client {
#service: Service;
constructor() {
this.#service = new Service();
}
c() {
this.#service.s();
}
}
class Service {
s() {
console.log("service");
}
}
結合度が高い
テストがしづらい
DI使用に書き換え
ClientはServiceの抽象にのみ依存している
code: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);
DIコンテナ
サービスロケータ
http://blog.a-way-out.net/blog/2015/08/31/your-dependency-injection-is-wrong-as-I-expected/
欠点
https://kbigwheel.hateblo.jp/entry/2018/06/08/224630
入力の数が増えすぎて、テストのパターンが増加する
関数に対してDI
『Dependency Injection Principles, Practices, and Patterns』
やはりあなた方のDependency Injectionはまちがっている。 — A Day in Serenity (Reloaded) — PHP, CodeIgniter, FuelPHP, Linux or something
用語も明確でわかりやすい
/kawasima/Dependency Injection
https://en.wikipedia.org/wiki/Dependency_injection
https://www.ulsystems.co.jp/topics/025
https://qiita.com/ritukiii/items/de30b2d944109521298f
https://qiita.com/hshimo/items/1136087e1c6e5c5b0d9f
/keroxp/DIの必要性もしくは言語的欠陥
https://speakerdeck.com/rukiadia/understand-dependency-injection-of-php