🙆‍♀️

DDDの集約の決め方サンプル例を使って0から考える

2023/01/15に公開約8,000字

ヨンデミーと言う会社でテックリードをしているrevenue-hackです!

今回はDDD+オニオンアーキテクチャで普段開発している傍らMENTAでDDD+オニオンアーキテクチャやクリーンアキテクチャを教えていて、集約の決め方がわからないといった声が多かったので、今回0からどのように考えていくのかを解説していきたいと思います。

会社の宣伝も入れさせてもらうと「日本中の子どもたちへ、豊かな読書体験を届ける」をミッションに掲げるスタートアップです!
GoやGraphQL、GCPで設計にも拘っている会社なので、興味のある方は是非!インターン生募集してます!

https://corp-yondemy.wraptas.site/recruit

記事の対象となる人

  • DDDを少しでも学びたい人
  • 設計に興味のある人
  • DDDを学んでいるけどつまずいている人

などの初心者を対象にしています。

ちなみにMENTAで教えているのはこちらのプランになります!
https://menta.work/plan/2217

DDDの集約の決め方の流れ(モデリングの流れ)

  1. ユースケースを洗い出す
  2. ユースケースからエンティティ、値オブジェクトを洗い出す
  3. ユースケースごとの集約をまとめていく
  4. 集約ごとの重複をチェックしてまとめて、ID参照に変更する

この順でやっていきます。

今回考慮しないこと

  • 集約に関して調べてくるユーザなら知っていそうなことは説明を省く
  • 実際のユースケースでこのユースケースは不自然じゃない?的なことは無視してください:bow:
  • 実際の実装方法については今回はやらない

とにかく初心者が集約を決める取っ掛かりとなるようにしています。

サンプルとなる題材について

今回はMENTAのプランを教えるときに実際に使っているMENTAを元に考えたユースケースを使います。
以下がサンプルユースケースになります。

サンプル例のユースケース図

具体的には以下になります。

  • ユーザ新規作成
    • 必須項目
      • 名前: 255文字以内
      • メールアドレス: 255文字以内
      • パスワード: 12文字以上,英数字それぞれ最低1文字以上
      • スキル
        • タグ名(選択式)
        • 評価: 1~5
        • 年数: 0以上のint型(5年まで)
        • 1つ以上
    • 任意項目
      • 自己紹介: 2000字以内
      • 経歴
      • 複数
        • 詳細: 1000字以内
        • 西暦from: 1970年以上のint型
        • 西暦to: 1970年以上のint型、西暦fromよりも大きい数字
  • ユーザ更新
    • 上記同様
  • メンター募集作成
    • 必須項目
      • タイトル: 255文字以内
      • カテゴリ(1つ)
        • プログラミング
        • マーケティング
        • デザイン
        • ライティング
        • 動画・映像
        • ビジネス
        • 語学
        • ライフスタイル
      • 相談形式
      • 単発
      • 継続
      • 相談方式
        • チャット
        • ビデオ通話
      • ディスクリプション(2000文字)
      • 予算(from円~to円)
        • 1000円以上の数値
      • 応募期間
        • 1日単位
        • 最大14日後まで可能
      • ステータス(公開or中止)
      • 公開・受付中止にすることができる
    • 任意項目
      • タグ(複数OK)
  • メンター募集に提案する
    • 提案内容: 2000文字以内
    • 提案できるのはスキルを5個以上持つユーザのみ
  • プラン作成
    • 以下必須項目
      • タイトル: 255文字以内
      • カテゴリ(1つ)
        • 上記のカテゴリ参照
      • タグ(5個まで)
        • 選択式
      • 内容
        • 2000文字以内
      • ステータス
        • 公開or中止
      • 料金体系
        • 月額or単発
        • 金額
    • 任意項目
      • 相談方式
        • チャットorビデオ電話
  • プラン契約リクエストを送る
    • メッセージ(最大500文字)
  • プランへの契約を承認する
    • メッセージ(最大500文字)

最終的に完成した集約はこちら(モデリング図)

結果のモデリング図は以下のような形になります!
集約サンプル例のモデリング図

サンプル例.pu

サンプル例を使ったDDDの集約の決め方

では実際に集約を決める手順について解説していきます。

ユースケースを出す

まず決め方としてユースケースで永続化するケースを抽出します。
ユースケースは先程上記に記載したので割愛します。

ユースケースからエンティティと集約を洗い出す

1つ1つのユースケースからエンティティと集約を出していきます。

集約とは?
DDDの集約とは、エンティティの集合体で整合性を保ちながらデータを更新する単位となります。

エンティティとは?
DDDのエンティティとは、一意なものを表現するオブジェクトです。
例えばMENTAサービスでいうとメンターは同じ「佐々木」という名字の方が複数人いても、それぞれ別々の人物のため一意のオブジェクトと考えることが出来、エンティティと呼ぶことが出来ます。
メンターエンティティはIDで識別することで名字が同じでも別の人物と把握します。逆に識別する必要のないものは値オブジェクトといいます。

まずは1つ1つのユースケースで永続化するデータを1つの集約として考えていきましょう!
今回はユーザ作成のユースケースで考えていきます。
ユーザ作成のユースケース図

エンティティ,値オブジェクトを洗い出す

エンティティ、値オブジェクトを出していきます。
エンティティ、値オブジェクトの出し方はRDBのテーブルを出すような感じでまずは出してみましょう。
※ただしDDDの手順としてはRDBのテーブルを考える前にモデリングを行います。あくまで考え方を伝えるためにテーブルを考える容量でやるという話です

テーブルで考えると
ユーザ作成ユースケースのスキーマ設計

のようになるので、

エンティティ、値オブジェクトは

  • ユーザ
  • スキル
  • 経歴
  • タグ

となります。
※今回は集約の決め方の例になるので、エンティティか値オブジェクトかは考慮しないです。

そうするとモデリング図に表すと
ユーザ集約サンプル例

こんな感じになります。

それぞれのユースケースごとに集約をまとめると、、、

一旦上記の方法で全てのユースケースで集約を作ってみると、、、

メンター募集集約
メンター募集集約例

プラン作成集約
プラン作成集約例

メンター提案集約
メンター提案集約サンプル例

契約集約
契約集約サンプル例

こんな感じになるかと思います。

集約の重複チェック

作成した集約を見ると色々なところでユーザやタグのオブジェクトが重複していることがわかります。

オブジェクトが重複しているのはおかしいので直していきます。

対処法としては「集約間ではIDを参照すること」で避けるようにしましょう!

結果どうなるかと言うと、、、

集約サンプル例のモデリング図

サンプル例.pu
こんな感じになりました!

基本的にはオブジェクトが重複している部分を集約のIDを参照するようにします。
ただ一点だけ複数の集約から参照されている「タグ」に関しては、別のオブジェクトとしてタグ集約を作りID参照するようにしています。

DDDにおける集約の決め方サンプル例のまとめ

今回はDDDで集約における決め方をサンプルを使ってまとめていきました。

DDDの集約の決め方は基本的にはこれで良いと思いますが、色々と集約をまたがないと行けなかったり、実装してみたらうまくいかないことが出てきたりと不都合も多々あるので、そのあたりはまた今後話していければと思います。

少しでもDDDやクリーンアキテクチャを学びたいという方は、こちらから気軽にメッセージください!
↓↓↓↓↓
https://menta.work/plan/2217

また普段設計や技術的な内容をツイートしてるので良かったらフォローしてください!
↓↓↓↓↓
https://twitter.com/tagaranoko1014

Discussion

ログインするとコメントできます