why
前回の記事で各層のモジュールを分離して
とりあえず Rest だけは動くようにした。
今回は Rest から Domain と Usecase のモジュールも使えるようにする。
Rest
Rest モジュールから Domain モジュールに何も依存を足さずにアクセスする
package com.kaede
パッケージ自体はこのように、Rest, Usecase, Domain, Port, Gateway, Driver, とすべて同じものを使っている。
一方、マルチモジュールにするためにモジュールを分割した。
なのでモジュール外部のクラスの関数を使うことはこのままではできない。
特に外部モジュールだということを意識せずに
同一モジュールにあった時と同様に Domain, Usecase を使ってみる。
@GetMapping("/persons") @ResponseBody fun getPersons(): String { val persons = personsUsecase.getAllPersons() val gson = Gson() val personsJson = persons.toJson() return gson.toJson(personsJson) }
toJson は Domain の拡張。
Caused by: java.lang.NoClassDefFoundError: com/kaede/PersonsUsecase
すると Usecase がみつからないとエラーがでて
アプリケーションが落ちる。
usecase だけを追加しても
e: /home/kaede/source/springboot/rest/src/main/kotlin/ com/kaede/PersonResource.kt: (18, 34): Cannot access class 'com.kaede.Persons'. Check your module classpath for missing or conflicting dependencies
Persons ドメインが見つからないとエラーでビルドできなくなる。
Rest の設定ファイルに Usecase と Domain の依存を追加
rest/bulid.gradle.kts に
dependencies { implementation(project(":usecase")) implementation(project(":domain")) }
usecase と domain のパッケージを読み込めるように設定する
その後に Gradle の象さんのポップアップしたリロードボタンを押す
基本的にはモジュール(プロジェクト)外のクラスは使えないが
こうすることでモジュール外のプロジェクトも読めるようになる。
2022-11-26 21:35:27.840 INFO 1943002 --- [ main] com.kaede.PersonApiApplicationKt : Started PersonApiApplicationKt in 1.915 seconds (JVM running for 2.309)
無事に起動できた。
Usecase
同様に Usecase からも他のモジュールたちが読み込めるようにする。
@Component class PersonsUsecase( private val personPort: PersonPort, ) { fun getAllPersons():Persons { return personPort.getAllPersons() }
Usecase の実装と
interface PersonPort { fun getAllPersons() :Persons }
Port の実装がこちら(実装というかインターフェイスだが)
依存の記述なしで起動する
Caused by: java.lang.NoClassDefFoundError: com/kaede/PersonPort
Port の依存を書かずに動かすと、当然 Port のクラスが
見つからないエラーが出る。
なので、Usecase の設定ファイル
build.gradle.kts に Port の依存を追加する
Domain の依存は自明。
dependencies { implementation(project(":domain")) implementation(project(":port")) // ... }
しかし、Port だけ追加しても
*************************** APPLICATION FAILED TO START *************************** Description: Parameter 0 of constructor in com.kaede.PersonsUsecase required a bean of type 'com.kaede.PersonPort' that could not be found.
PersonPort はみつからないとでてしまう
dependencies { implementation(project(":domain")) implementation(project(":port")) implementation(project(":gateway")) // ... }
Port の先の Gateway まで Usecase の依存に追加する。
2022-11-26 21:46:12.453 INFO 1945207 --- [ main] com.kaede.PersonApiApplicationKt : Started PersonApiApplicationKt in 1.999 seconds (JVM running for 2.418)
すると無事に起動するようになる。
以前作成した図を参照する。
Gateway が必要なのは、Port は単なる穴であるからだ。
穴単体を覗くという行為は成立しない。
穴の先が有るから、穴を覗けるのだ。
だから Port という穴と、同時に穴の先に存在する Gateway を、
Usecase からは依存として必要になる。
まとめ
クリーンアーキテクチャで各層ごとにモジュールを分離した。
その後、正常に動作させるためには
各モジュールの依存先として
- Rest モジュールの build.gradle.kts
- Domain
- Usecase
- Usecase モジュールの build.gradle.kts
- Domain
- Port
- Gateway
まず、これらの記述が必要になる。
以上。
Top comments (0)