前回に引き続きかとじゅんさんによる勉強会の第4弾で、ドメインモデリングワークショップの2回目を開催していただきました。
前回のワークショップでは、かとじゅんさんのドメインモデリングワークショップを参考にWalletアプリケーションで登場する概念のモデリングを行いました。
今回のワークショップではそのモデルを利用する側や保存する側などにもフォーカスして、アプリケーションの1つの機能として通して動作するよう実装していきました。
クリーンアーキテクチャ
始めに前回のワークショップのおさらいと、1つの機能を通して実装するに当たりクリーンアーキテクチャの解説をしていただきました。
その後JavaチームとScalaチームに分かれ、各チームはモブプログラミングの形式で実装を行っていきました。
前回のワークショップで作成したアプリケーションを、まずはクリーンアーキテクチャの構成に変更していきました。
かとじゅんさんのクリーンアーキテクチャの記事で紹介されている構成を参考にinterface-adaptor
、contract-interface-adaptor
、use-case
、domain
、infrastructure
というプロジェクトを作成し、依存関係を定義しました。
以下はその記述の一部です。(JavaチームではGradleを使用しています)
build.gradle
project(':interface-adaptor') {
dependencies {
compile project(':contract-interface-adaptor')
compile project(':use-case')
compile project(':domain')
}
}
project(':contract-interface-adaptor') {
dependencies {
compile project(':domain')
}
}
project(':use-case') {
dependencies {
compile project(':contract-interface-adaptor')
compile project(':domain')
compile project(':infrastructure')
}
}
project(':domain') {
}
project(':infrastructure'){
}
各プロジェクトが上位のプロジェクトに依存しないことを実装者に強制するために、パッケージではなくプロジェクトで分けるという方法が印象的でした。
Wallet作成のユースケース
今回取り組んだのはウォレットの作成というユースケースでした。
アドバイスをもらいながら、Walletの識別子をULIDを用いたものに変更したり、金額をint型からMoney型という値オブジェクトに変更するというリファクタリングを進めつつ、今回新たに作成したuse-case
やinterface-adaptor
についても実装していきました。
interface-adaptor
に作成したWallet用のRepositoryはメモリ上に保存する実装をしたのですが、これはcontract-interface-adaptor
にあるWalletRepositoryというinterfaceを実装しています。
後に保存先がDBになった場合でも、contract-interface-adaptorに定義したinterfaceを守った上で新しいRepositoryを実装することでuse-case
やdomain
が隔離されinterface-adaptor
の変更に左右されなくなるので、クリーンアーキテクチャのメリットを体験できる良い機会になりました。
最後に
今回のかとじゅんさんによるワークショップではDDDとクリーンアーキテクチャを用いて実際にアプリケーションの1つ機能を通して実装しました。
ドメインモデリングのワークショップを始めるにあたって、参加者から「Evans本やIDDD本を読んだが実際のプロジェクトにどう適用していけばいいかわからない」という意見をもらっていたのですが、この2回のドメインモデリングワークショップに参加して、「ずいぶん実装のイメージが掴めた」という言葉を貰え、非常に有意義な勉強会となりました。
今後は実装に対する理解を深めていきつつも、よりドメインを深く理解するという考え方や手法についてもフォーカスして知見を深めていきたいと考えています。