はじめに
- 依存性の注入って稀に良く聞くけど何それよく分からん怖いって人(私)向けに書きました。
- DIライブラリの使い方からDIを学ぼうとすると困難だったので、まずはDIとは?についてまとめています。
- DIを行う組み立て役の係
Assembler
が居ること、依存性という単語ではなく依存オブジェクト
と念頭に置いとくと理解しやすいです。
Dependency Injection(依存オブジェクト注入)とは
- DIとは、Controllerが使用したい依存オブジェクトを第三者オブジェクトが生成/代入する概念のこと。
- 依存オブジェクトを生成/代入をする第三者オブジェクト
Assembler
を導入する必要がある。 - 前提としてClassの公開済みの振る舞いとしてProtocol/Interface相当で定義する必要がある。
- Protocol/Interfaceを使用しないスタイルでコーディングしているならば、DIの恩恵は受けられないのでDDDなど設計手法を先に学んだほうが良い。
依存オブジェクトとは
Swift
class Controller {
let property: Object = ObjectImpl()
}
の ObjectImpl()
ControllerとしてはObjectを扱いたいが、ObjectImplを使用したいわけではないので、ObjectImplには本質的に関心がない。
= Objectのみ知っていれば良い
しかし、実際にはObjectImplを元にObjectを生成しているため、ObjectImplに依存してしまっている。
依存の問題
- 依存オブジェクトの汚染範囲
- ObjectImplをObjectImpl2に差し替えたい(例:ToyotaCar→SubaruCarにしたい等)
- 依存しているControllerの修正も必要
- ObjectImplを使用しているController数に比例してしまう。
- ObjectImplをObjectImpl2に差し替えたい(例:ToyotaCar→SubaruCarにしたい等)
解決策
第三者となるAssembler
がオブジェクト生成し、Constructor/Setterなどで渡せば良い。
それをDependency Injectionと呼ぶ。
具体的な実装方法は色々あるが、代表的なのはConstructor Dependency Injection
※他にSetter Dependency Injection、Interface Dependency Injectionがあるが、推奨はConstructor Dependency Injectionとされている。
Constructor Dependency Injection
class Controller {
let property: Object
init(property: Object) {
self.property = property
}
}
ObjectImplへの依存が無くなり、ObjectImplの修正/ObjectImpl2などへの差し替えが可能に。
しかし、まだ問題がある。
プロパティ数が増えるとコンストラクタが汚くなってしまう
class Controller {
let property: Object
init(property: Object, property2: Object, property3: Object) {
self.property = property
self.property2 = property2
self.property3 = property3
}
}
ライブラリの利用
参考
- Inversion of Control Containers and the Dependency Injection patternの日本語訳
- 注)こちらの参考記事でも依存性注入ではなく、依存オブジェクト注入と訳されています。