Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
[モダンアプリ勉強会] DDDのことはじめ
Search
坂本 勇人
September 06, 2026
110
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
[モダンアプリ勉強会] DDDのことはじめ
坂本 勇人
September 06, 2026
Featured
See All Featured
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
590
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
520
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
287
14k
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
11k
Ethics towards AI in product and experience design
skipperchong
2
360
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
510
Designing for Performance
lara
611
70k
Leveraging Curiosity to Care for An Aging Population
cassininazir
1
490
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.8k
The Limits of Empathy - UXLibs8
cassininazir
1
630
New Earth Scene 8
popppiees
3
2.5k
Transcript
DDDのことはじめ 2026/07/27 坂本 勇⼈
⾃⼰紹介 • 名前 • • • 坂本 勇⼈(Sakamoto Yuto) 所属
• クラウド事業統括本部 • モダンアプリコンサルティングチーム 普段のお仕事 • お客さんのスクラムに参加して要件定義から開発までのお⼿伝いをしてます • 実装するのが好きですが、アーキ考えてるのも好き
本⽇のスコープ
はじめに 本⽇は⼩難しいことを、できるだけ⼩難しくなく話すつもりです ⼩難しく感じる部分もあるかもしれませんが、 できるだけわかりやすく説明できるよう頑張ります 構成要素にも触れますが、思想やメリットに重きを置いてます これから⼊⾨したいという⽅を対象としています
⽬次 1. オープニング 2. ドメインとは / DDD とは 3. メリット
→ 本当に守れる?(⼊⼝‧永続化‧Repository) 4. いつ DDD する? 5. 構成要素(Entity → Value Object → Aggregate) 6. 集約の切り⽅ 7. クロージング
DDDのイメージ DDDに関して - よく聞くけど難しそう - 学習コスト⾼そう - 維持するの⼤変そう こんなイメージありませんか?
DDD できちんと設計するのは難しい
なにが難しい? DDD の考え⽅(概念構造として捉える)は共通でも、 設計の答えは⼀つに決まらない (画⼀的な正解がない)
なにが難しい? 他にも • エンジニア間でルールとして徹底するのが難しい • 技術的課題解決との両⽴には、DDD だけでは⾜りないことも多い
だけど...
「ドメインを概念構造として捉える」という考え⽅は役にたつ
本⽇持ち帰って欲しいもの • DDD ってどういうもの? • DDD のメリット • DDD を始めるための構成要素
◦ Entity ◦ Value Object ◦ Aggregate(集約)
今⽇話さないこと 戦略的 DDD • サブドメイン • Bounded Context 集約を跨ぐようなロジックの実現⽅法 •
Domain Service • Domain Event
今⽇話さないこと その他の周辺技術‧実装 • Repository の具体実装(ORM‧SQL‧UoW など) • Clean Architecture や
CQS などとの組み合わせ
考え⽅とメリット
ドメインってなに? ビジネス⽤語からイメージする 「お客様のビジネス全体に関する知識」 とは範囲が異なる
ドメインってなに? 業界の知識のすべてをコードに⼊れるわけではない
ドメインってなに?(例) 例えば 図書館の本の管理システム があったとして… 図書館業務の知識全体 ≠ 本の管理システムが担うドメイン (アプリにとって必要な領域に絞る)
ドメイン駆動設計(DDD) とは? ドメイン(システムが扱う問題領域)の概念構造を、ソースコードに反映す るアプローチ → ドメインモデリング ドメインの知識をクラス‧メソッド‧名前で表現する • プロパティ •
振る舞い • 不変条件
本棚のアプリのドメインモデリングをしてみる
概念の構造化 本棚の管理アプリには 本棚 と 本 の概念がある 別の持つ概念なのでそれぞれを クラス として表現する Bookshelf
/ Book
プロパティの付与 本棚‧本には、それぞれ 固有のプロパティ がある それをクラスに 内包する 例: 本棚 → 容量
∕ 本 → 管理番号‧タイトル
所有関係の整理 本棚の管理アプリでは本は 本棚に⼊っている ものとする (野良の本は存在しない) なので 本は本棚が管理 する Bookshelf.books: Book[]
振る舞いの定義 本棚から本を 出し⼊れ できる 出し⼊れできるよう、addBook() / removeBook() という振る舞いを作る
不変条件の追加 本棚には容量を超えた本は⼊れられない addBook() で容量を超えていないか検証する 守らなければいけないルール=不変条件
寄り道:不変条件(invariant) ビジネス上、絶対に壊してはいけない約束 違反すると、ドメイン的に 「壊れた状態」 本棚の例: 現在の冊数 ≦ 容量 → 容量オーバーした本棚は存在してはいけない
全体の流れ
完成図
何がうれしいか 概念構造を表現したコードの中で、 守るべきルールを コードの中に閉じ込めやすい (どう閉じ込めるか は、後ほど説明)
何がうれしいか • オブジェクトが 「実務上で何を表しているか」 を理解しやすい • コードとビジネスの構造が近くなることで 変更に強くなる ◦ アプリの機能が変わってもドメインは影響を受けづらい
不変条件:さっきのコードで本当に守れる? 例えば先ほどBookshelfの addBook() に容量チェックを書いたが、 これで 本当に容量超過は防げる?
不変条件:さっきのコードで本当に守れる? → このままでは守れない addBook() を書いただけでは 不⼗分 本と本棚を 別々に 操作 できると、
そのルールを守る処理が コード上で必ず通る形になっていない (どこかでチェックしても、別の更新経路ですり抜けうる)
ルールを守るには? ルールをチェックする処理が、必ず通る道を作る必要がある
更新可能なまとまりを制限する • Book / Bookshelf を 別々に 更新できる → addBook()
をすり抜けたBookができてしまう • Bookshelfしか更新できない → Bookを追加するためには addBook() しなければいけない Bookshelfの形でしか更新できなくすることでルールを守らせる → 整合が保証されたまとまり= 集約
更新のまとまり
Repository とは データの永続化を担うレイヤ 受け取るのは必ず 集約(Aggregate) • BookshelfRepository.save(bookshelf) → OK •
BookRepository.save(book) → NG
ここまでのまとめ • 守るべきルール(不変条件) がある • 更新経路が 複数 だとルールが破れる • 集約
+ Repository で守る
いつやる? では、この⼿の設計を、いつやる価値があるか?
いつ DDD を検討するか 2つの段階に分けて考える 考え方 実装 内容 概念構造として捉える Entity /
集約 / Repository まで整える 度合い 常に 役に立つ 規模・難易度 次第
いつ DDD を検討するか 本棚の例は、向いている寄り 観点 向いている 過剰になりやすい ルール 複雑なルールがある (本棚の容量など)
入力チェック程度で足りる 更新 入口が複数ある CRUD 1本で問題ない 知識 仕様が 属人化 している CRUDで回せる程度 寿命 長く運用 する 使い捨て
全部DDDしないといけない? いきなり「全部 DDD」ではなくても良い • 容量ルール‧本の所在 がある → 集約までやる価値あり • 本棚のマスタ登録
→ Entity 1個 + CRUD でも⾜りる 複雑なところから。シンプルな部分はシンプルなままでも良い
概念構造の構成要素
構成要素に名前を付けると 先ほど話題に出した 集約(Aggregate) と呼ばれる構造物は、その中⾝を構 成する要素が存在します 中⾝に名前を付けると… 集約の中⾝ = Entity‧Value Object
Entity とは 「もの」 を表す 本棚‧本‧貸出履歴のように、業務上の実体をイメージしやすい (必ずしも現物とは限らない)
Entity の特性 • 同⼀性(ID) で区別される ◦ • 属性を持つ ◦ •
IDが同じであれば同⼀のオブジェクト プリミティブな値(例: title: string)、またはValueObject 状態が変わる(Mutable)
Entity のコード例(Book)
Value Object とは 「値や概念‧ルール」 を表す Entityの属性を、ルール付きの型にするイメージ • 形式チェックが必要なメールアドレス • 前後関係の保証が必要な期間(From
- To)
Value Object の特性 • 値の等価性で⽐較(ID による同⼀性はない) • プリミティブな値を 1つ以上 内包し意味とルールを閉じ込める
◦ • 複数の値間で整合をとる必要がある場合2つ以上の値を所有する 値が変わらない(Immutable) ◦ Value Objectに内包されている値は直接書き換えない ◦ Entityの所有するValue Objectに変更を加えたい場合、新しいValue Objectと差し替え る
Value Object のコード例(Capacity)
Value Object(補⾜) EntityのIdも Value Object として表現することが多い BookId と BookshelfId の取り違えを防ぐ⽬的がある
(TypeScriptの場合要ブランド化)
集約(Aggregate)とは 整合性を守るべきまとまりのこと 単⼀のEntityを 集約ルート とし、集約 内の整合性が保証される境界 本棚のアプリでの本棚 Repository で扱える単位
集約(Aggregate)の特性 • 1つの集約につき、集約ルートととなるEntityが必ず1つ存在する • 外部からの⼦の操作は必ず 集約ルートを経由する ◦ • Bookshelfの books
は addBook/removeBook で操作する ⼦となるEntityが存在しないEntityは、そのEntityをルートとする単独の 集約と⾔える ◦ 単独で整合が保証されており読み書きが可能である
ドメインオブジェクト と物理モデルは別 ドメインオブジェクト は ドメイン上の概念 テーブル‧カラムとは 必ずしも 1:1 にならない 1:1
である必要もない
ドメインオブジェクト と物理モデルは別ーズレの例
集約のコード例(Bookshelf)
集約の切り⽅ 判断基準: 常に⼀緒に整合性を保つべき不変条件があるか 親⼦関係がある ≠ 必ず 1 集約 パターン 例
同一集約内 本棚 + 本 + 容量 分ける 組織とメンバー (跨いだ不変条件がない)
本⽇のまとめ 1. DDD = ドメインの概念構造をコードに反映する 2. 守りたいルールは 「必ず通る道」 で守る →
集約 + Repository 3. メリット = バイパスしにくい / 読みやすい / 変更に強い 4. 考え⽅は常に有⽤、実装は複雑なところから 5. 構成要素 = Entity / Value Object / Aggregate 集約は迷ったら 不変条件 で切る
None