DEV Community

kaede
kaede

Posted on • Updated on

Kotlin Springboot -- Part 10 Port という interface を作って Usecase と Gateway をつなぐ

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
}
Enter fullscreen mode Exit fullscreen mode

名前と返り値の型だけ定義


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)
      )
    })
  }
}
Enter fullscreen mode Exit fullscreen mode

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)
  }
}
Enter fullscreen mode Exit fullscreen mode

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
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Rest は何も変わらず、これでクリーンに API が分離できた。

依存性逆転、中央に依存性を持ってくることができたのだ。


まとめ

クリーンアーキテクチャで依存性逆転をしたい時は

Port にインターフェースを作って

そこから Gateway で実装を書いて

Usecase では @Component の依存性注入で Port を入れて
Port の関数を呼ぶようにする。それで Gateway が呼ばれる。

これでようやく

Image description

Rest > (Domain) > Usecase > Port > Domain > Gateway > Driver

というクリーンアーキテクチャの 6 層の分離ができた。

Top comments (0)