クラス間結合を疎にして実装したい場合に、DI(Dependency Injection)の手法を使いますが、
static な関数/値をそのまま使うと結合してしまって入れ替えができなくなりますよね。
static でもDI するやり方を調べたのでメモ。
1.static な関数(変数)を宣言したプロトコルを定義します。
protocol Animal {
static func say()
}
2.プロトコルを実装します。
class Cat: Animal {
static func say() {
print("nya-")
}
}
class CatMock: Animal {
static func say() {
print("mock nya-")
}
}
3.メタタイプ(.Type
)のメンバ変数を定義して、初期化時に inject します。
class Owner {
private let animal: Animal.Type
init(animal: Animal.Type = Cat.self) {
self.animal = animal
}
func say() {
animal.say()
}
}
4.呼び出して使います。
// 普通に使う時
let owner = Owner()
owner.say()
// テスト書く時
let ownerTest = Owner(animal: CatMock.self)
ownerTest.say()
あまり状態を持たない処理を作ることができればテストしやすくなります。
メンバ変数にアクセスしない処理などは積極的に static にしていってもいいかなと思いました。