こんにちは!株式会社Holmesでエンジニアをしている平田です。
Holmesでは、現在、プロダクト開発にドメイン駆動設計を取り入れようと、社内で勉強会の開催や各メンバーが勉強したことを共有しあったりしています。
ドメイン駆動設計に取り組むにあたって、大切なことのことの一つにより良いモデルを作成する、モデリングがあります。
今回はそんなモデリングをPlantUMLで行う方法について、一例をご紹介できればと思います。
※本記事のモデリング手法は以下の書籍を参考に行なっております。
PlantUMLとは
PlantUML(github)とは、オープンソースのUMLダイアグラム作成用の言語です。
本記事ではVisual Studio Codeの拡張機能を用いています。(PlantUMLのセットアップは拡張機能の説明をご覧ください)
なぜPlantUMLを用いるのか
モデリングを行う方法はオンライン・オフライン問わずいくらでも存在すると思います。
弊社でも、オンラインホワイトボードのmiroを使ったりしています。
その中で、PlantUMLを使う利点としては、プレーンテキストで記述できるため、Gitなどのバージョン管理システムで管理できることではないでしょうか。
PlantUMLで記述したモデルをバージョン管理することによって、コードレビューのプロセスに乗せたり、変更を追っていくことができるようになります。
ユースケース図
まずはユースケースを作成します。
今回は、Nizi Projectをドメインとして作成します。
Nizi Project(ニジプロジェクト)は、韓国大手事務所JYPエンターテイメントとソニーミュージックによる共同ガールズグループプロジェクトである。
(Wikipediaより)
このオーディションに合格したメンバーはNiziUとして2020/12/02にデビューします。(ついでに覚えて帰ってね)
全体像
@startuml NiziProject actor プロデューサー left to right direction rectangle { プロデューサー -- (キューブをあげる) プロデューサー -- (テストを進める) プロデューサー -- (パート1脱落者を決める) プロデューサー -- (パート2脱落者を決める) プロデューサー -- (合格者を決める) } @enduml
たったこれだけでユースケース図を作成することができます。
記述内容の詳細を説明します。
@startuml,@enduml
これは開始と終了をそれぞれ表しています。
@startuml @enduml
actors
actor プロデューサー
で人の形をした図が表示されラベルを設定することができます。
:プロデューサー:
と記述することもできます。
usecases
プロデューサー -- (キューブをあげる)
ではユースケースとactorとの関連を表現しています。--
と記述することで関連を線でつなぐことができます。
ユースケースはusecase キューブをあげる
と書くこともできますが、今回は定義と関連付けを同時に行いたかったので(キューブをあげる)
と記述しています。
left to right direction
は関連の方向を指定しています(作成したい図に合わせて調整してみてください)。
rectangle
rectangle {}
はブロック内に記述することで枠に囲われたように表現することができます。見た目やスコープのために記述しています。
ドメインモデル図
ドメインモデル図は冒頭に紹介した書籍に沿ったルールで作成します。
- ルールを吹き出しに記述する
- オブジェクトの関連を記述する
- 多重度を記述する
- 集約の範囲を記述する
全体像
@startuml NiziProject skinparam PackageStyle rectangle package 候補者集約 { object 候補者 { 候補者ID パート1脱落 パート2脱落 合格 オーディションID } object 名前 { 姓 名 ニックネーム } object ペンダント { パート1キューブ パート2キューブ } object キューブ { キューブ名 } } note left of ペンダント * ペンダントにはそれぞれ4つのキューブをはめることができる。 * パート1用キューブは重複できず決められた4種類、 パート2用キューブは最大4つはめることができる。 end note note bottom of キューブ * キューブは5種類存在する。 * パート1キューブ(「ダンス」「ボーカル」「スター性」「人柄」) * パート2キューブ end note note right of 候補者 * パート1で脱落した候補者はパート2キューブを獲得できない * パート2で脱落した候補者も以降、パート2キューブを獲得できない end note 名前 "1" -left-* "1" 候補者 ペンダント "1" -down-* "1" 候補者 キューブ "0..8" -down-* "1" ペンダント package オーディション集約 { object オーディション { オーディションID オーディション名 現在テスト } object テスト { テスト名 パート 順序 } } note right of オーディション * テストの順番は決められている。 end note note right of テスト * テストは1オーディションにつき、パート1に4回、パート2に4回ある * テストで獲得可能なキューブは決められている。 * パート1テスト1~3は決められたパート1キューブを1つ、 テスト4ではパート1キューブ最大4つ獲得できる。 * パート2テスト1~3まではパート2キューブ1つ、 テスト4ではパート2キューブ最大4つ獲得できる。 end note 候補者 "1..n" -down-> "1" オーディション テスト "8" -down-* "1" オーディション テスト "1..4" -down-> "1..4" キューブ @enduml
記述内容の詳細を説明します。
packages
skinparam PackageStyle rectangle
はパッケージのスタイルを変更するために記述しています。様々なスタイル変更を施すことができるので、興味がある人は調べてみてください。
package 候補者集約 {}
集約を表現しています。ブロック内に記述することで集約内であることを表現できます。
objects
object 候補者 {}
はオブジェクトです。ブロック内には属性を記述することができます。
notes
吹き出しでルールを記述することができます。以下は改行の表現で、end note
までの間に文章を記述し、改行が反映されます。また、インデントが揃っていれば、吹き出しはインデントされませんが、インデントがずれている場合、最もインデントが少ない行をスタートとしてインデントが反映されます。改行が不要な場合、note left of ペンダント: コメント
と簡潔に記述することもできます。
note left of ペンダント 改行 できる end note
direction
left
は吹き出しをオブジェクトに対してどの方向に表示するかを指定できます。(left、right、top、bottom)
relations
名前 "1" -left-* "1" 候補者
は多重度とオブジェクト間の関連を表現しています。
-left-*
は関連になりますが、--
の間にleftと入れることで関連を表示する方向を決めることができます。(left、right、up、down)
label
終端の*
はいくつかの種類があり、始端と終端両方に記述が可能です。ドメインモデル図では*
または>
しか登場しません。
関連付けるオブジェクトと関連付けの間に""
(ダブルクォート)で囲んで文字を記述することで多重度の表現ができます。
振り返り
私自身、この記事で初めてモデリングを行いました。
ドメインモデル図を見ていただらいたらわかるように、テストのルールが多かったり、キューブがテスト・候補者の双方に深く関連しているように見えます。
今回は、「キューブをあげる(候補者がキューブを受け取る)」ユースケースを鑑みてこのようなモデリングを行いましたが、ユースケースや今後の展開によっては、キューブ集約やテスト集約といった形に変更していくことも考えられます。
モデリングは最初に作成したら終わりではなく、コード同様、常に変更し、より良いモデルに改善していくことが重要です。
モデルをPlantUMLで記述してバージョン管理していくメリットが活きてきますね!
最後に
いかがでしたでしょうか。
PlantUMLを用いたドメイン駆動設計のモデリングが容易にできることがわかっていただけたと思います。
是非活用していただければ幸いです。
Holmesではエンジニア・デザイナーを募集しております。ご興味がある方はこちらからご連絡ください。