Kotlin Springboot -- Part 10 Port という interface を作って Usecase と Gateway をつなぐ
kaede
Posted on September 21, 2022
why
前回まで、CA で必須である Port を省略していた。
https://dev.to/kaede_io/kotlin-ji-chu-part-5-abstract-class-to-interface-nowei-i-aok
この Kotlin 基礎の回で Port で使われる interface の使い方を理解したので入れてみる。
interface である Port を作る
package com.example.springboot
interface PersonPort {
fun getAllPersons(): Persons
}
名前と返り値の型だけ定義
Gateway をインターフェースから実装するようにする
Kotlin の文法に従って interface の中身を実装する。
クラスに実装元?の interface を書く。型みたいに。
override を関数につけて中身を書く。
クラスの引数では Driver のインスタンスを取れなくなる。
なのでクラス外部に Driver のインスタンスを作成して
そのインスタンスをクラスの内部の関数で使う。
package com.example.springboot
import org.springframework.stereotype.Component
val personsDriver = PersonsDriver()
@Component
class PersonsGateway: PersonPort {
override fun getAllPersons():Persons {
val persons = personsDriver.findAll()
return Persons(persons.map { person ->
Person(
Name(person.name),
Age(person.age)
)
})
}
}
Usecase で Port から Gateway の関数を呼び出す
class PersonsUsecase(
private val personPort: PersonPort,
) {
fun getAllPersons():Persons {
println("Usecase/")
println("getAllPersons/")
return personPort.getAllPersons()
}
fun getPersonsByAge(age: Age):Persons {
val persons = personPort.getAllPersons()
return persons.filterByLessThan(age)
}
}
Usecase では引数を Gateway のインスタンスから Port のインスタンスに変更する。
そして Port のインスタンスから呼ぶと、Gateway のインスタンスにつながる。
Rest
// 20220921234906
// http://localhost:8080/persons
{
"persons": [
{
"name": "taro",
"age": 3
},
{
"name": "hana",
"age": 5
},
{
"name": "Dominique",
"age": 11
},
{
"name": "Jackson",
"age": 11
}
]
}
Rest は何も変わらず、これでクリーンに API が分離できた。
依存性逆転、中央に依存性を持ってくることができたのだ。
まとめ
クリーンアーキテクチャで依存性逆転をしたい時は
Port にインターフェースを作って
そこから Gateway で実装を書いて
Usecase では @Component
の依存性注入で Port を入れて
Port の関数を呼ぶようにする。それで Gateway が呼ばれる。
これでようやく
Rest > (Domain) > Usecase > Port > Domain > Gateway > Driver
というクリーンアーキテクチャの 6 層の分離ができた。
Posted on September 21, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
October 12, 2022
September 21, 2022
September 10, 2022
September 8, 2022