8
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Swift】Dependency Injectionに慣れよう

Posted at

#はじめに
Dependency Injection(以下DI)はテストコードを書きやすくするために用いられることが多い手法です。
DIは二種類あるので、一つ一つ見ていきましょう。

#コンストラクタインジェクション
コンストラインジェクションはイニシャライズするときにインスタンスを注入します。
①プロトコルを用意する
②用意したプロトコルに準拠するクラスを用意する
③イニシャライズするときに準拠したクラスを注入する

// ①プロトコルを用意する
protocol UserRepositoryProtocol {
    func login()
}

// ②用意したプロトコルに準拠するクラスを用意する
// 本番用クラス
class UserRepository: UserRepositoryProtocol {
    func login() {
        print("本番")
    }
}

// ②用意したプロトコルに準拠するクラスを用意する
// 偽物クラス
class UserRepository偽物: UserRepositoryProtocol {
    func login() {
        print("偽物")
    }
}

class UserUseCase {
    private let repository: UserRepositoryProtocol
    init(repository: UserRepositoryProtocol) {
        self.repository = repository
    }
    func login() {
        repository.login()
    }
}

let repositroy = UserRepository()
// let repository偽物 = UserRepository偽物()
// ③イニシャライズするときに準拠したクラスを注入する
let userUseCase = UserUseCase(repository: repositroy)
userUseCase.login() // 本番

具体的なRepositoryクラス(UserRepositoryやUserRepository偽物)にUserUseCaseが依存するのではなく、インターフェース(プロトコル)に依存し、具体的なクラスをUserUseCaseをイニシャライズするときに注入します。これにより、本番用クラス(UserRepository)と偽物クラス(UserRepository偽物)をインスタンスする箇所で簡単に切り替えられるのでテストコードが書きやすくなります。

#セッターインジェクション
セッターインジェクションはイニシャライズした後にコンポーネントを注入します。

protocol ViewModelProtocol {
    func printName()
}
class ViewModel: ViewModelProtocol {
    func printName() {
        print("REON")
    }
}
class ViewController: UIViewController {
    private var viewModel: ViewModelProtocol?
    func inject(viewModel: ViewModelProtocol) {
        self.viewModel = viewModel
    }
    func printName() {
        viewModel?.printName()
    }
}
let vc = UIStoryboard(name: "VC", bundle: nil)
    .instantiateInitialViewController() as! ViewController
let viewModel = ViewModel()
vc.inject(viewModel: viewModel) // 注入
vc.printName() // REON

UIViewControllerをUIStoryboardから初期化する場合、コンストラクタインジェクションを使えないので、セッターインジェクションを用います。
しかし、セッターインジェクションは注入し忘れる可能性があるので、コンストラクタインジェクションを基本的に使えば良いでしょう。

#おわりに
DIはよく使うのでこれを機にマスターしておきましょう。

8
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?