10章のメモ
- 依存関係逆転の原則は
UseCaseOutputPort
によって実現 - Use Case が見ているのはあくまで「入出力のデータを受け取れるオブジェクト」であり、
Presenter の具体的なクラスではない
// インターフェイスアダプター(Controller / Presenter) -> Use Case
// Use Case(内)
protocol UseCaseOutputPort: AnyObject {
func useCaseDidUpdate(value: Int)
}
protocol UsecaseInputPort {
func update(something: Int)
}
final class UseCase: UsecaseInputPort {
private weak var output: UseCaseOutputPort?
init(output: UseCaseOutputPort) {
self.output = output
}
func update(something value: Int) {
// (値を使ったアプリケーション固有の処理)
// (ここでは Entity 層の処理・データも使える)
// Output 経由で Presenter へ通知(逆方向)
output?.useCaseDidUpdate(value: value)
}
}
// インターフェイスアダプター(外)
final class Presenter: UseCaseOutputPort {
func useCaseDidUpdate(value: Int) {
print("UI 更新(\(value))")
}
}
final class Controller {
private let useCaseInput: UsecaseInputPort
init(input: UsecaseInputPort) {
useCaseInput = input
}
func received(something value: Int) {
// Input 経由でUse Case を呼び出し(順方向)
useCaseInput.update(something: value)
}
}
// 円の構築
let useCase: UseCase = .init(output: Presenter())
let controller: Controller = .init(input: useCase)
// 処理開始
controller.received(something: 10)
『オブジェクト指向設計実践ガイド(Sandi Metz著)』より
依存オブジェクトの注入 (dependency injection)
https://github.com/noriyotcp/practical_object_oriented_design_in_ruby/blob/master/03_Managing_Dependencies/02.md