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について勉強したので5分でまとめる
Search
y_ahiru
August 28, 2018
Programming
0
340
DDDについて勉強したので5分でまとめる
1ヶ月ほどDDDについて勉強したので、その成果を5分でLTしました。
y_ahiru
August 28, 2018
Tweet
Share
More Decks by y_ahiru
See All by y_ahiru
恣意性から考える、変更に強いモデルの作り方
yahiru
1
970
責務と認知負荷を整える! 抽象レベルを意識した関心の分離
yahiru
11
2.4k
さいきょうのレイヤードアーキテクチャについて考えてみた
yahiru
3
990
フロントエンドエンジニアも知っておきたい HTTP/3 で変わること
yahiru
16
13k
ゆるふわCQRS入門
yahiru
2
690
設計におけるソリューションドメイン
yahiru
3
1.7k
PHPで始めるGitHub Actions
yahiru
1
790
5ヶ月でカバレッジを20%から90%にあげた話
yahiru
2
6.7k
入門ミューテーションテスト/ A bigginer's guide to Mutation testing
yahiru
0
1.5k
Other Decks in Programming
See All in Programming
decksh - a little language for decks
ajstarks
4
21k
tool ディレクティブを導入してみた感想
sgash708
1
150
TanStack DB ~状態管理の新しい考え方~
bmthd
2
330
モバイルアプリからWebへの横展開を加速した話_Claude_Code_実践術.pdf
kazuyasakamoto
0
260
Constant integer division faster than compiler-generated code
herumi
2
690
Scale out your Claude Code ~自社専用Agentで10xする開発プロセス~
yukukotani
9
2.6k
CEDEC2025 長期運営ゲームをあと10年続けるための0から始める自動テスト ~4000項目を50%自動化し、月1→毎日実行にした3年間~
akatsukigames_tech
0
150
CEDEC 2025 『ゲームにおけるリアルタイム通信への QUIC導入事例の紹介』
segadevtech
3
970
コンテキストエンジニアリング Cursor編
kinopeee
1
700
コーディングエージェント時代のNeovim
key60228
1
100
新世界の理解
koriym
0
140
MLH State of the League: 2026 Season
theycallmeswift
0
160
Featured
See All Featured
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
33
2.4k
GraphQLの誤解/rethinking-graphql
sonatard
71
11k
Visualization
eitanlees
147
16k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
126
53k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
32
1.4k
Stop Working from a Prison Cell
hatefulcrawdad
271
21k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
18
1.1k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
229
22k
Faster Mobile Websites
deanohume
309
31k
Designing for Performance
lara
610
69k
Code Review Best Practice
trishagee
70
19k
Build The Right Thing And Hit Your Dates
maggiecrowley
37
2.8k
Transcript
DDDの勉強をしたので5分でまとめる
自己紹介 吉田です Twitter @strtyuu
ドメイン駆動設計とは? ドメインを モデリングして モデリングして モデリングし続ける設計手法のこと
ドメインとは? アプリケーションが解決したい問題そのもののこと
モデリングとは? モデルの振る舞いを定義していく作業のことを指します。
モデルとは? ドメインを構成する様々な要素のこと
たとえば 会議室の予約システムを作りますとなった場合 会議室はもちろんモデルになると思いますし 予約という概念もモデルになります。
モデリングのやり方 ドメインエキスパートとドメインについて話し合って 話し合いを設計に反映させて 設計を元に実装をして ドメインエキスパートとドメインについて話し合って 話し合いを設計に反映させて 設計を元に実装をして ドメインエキスパートと...
以下エンドレス
モデルがどんどん更新されてゆく 実装は更新されてゆくモデルについていかなければならない つまり、変更に対して柔軟な実装になっていないと、 ドメイン駆動設計っていうのは、実現できない
柔軟な実装をするために デザインパターンを駆使して、複雑さに立ち向かう Repository Entity ValueObject Layered Architecture Aggregate 他
レイヤードアーキテクチャ アプリケーションをいくつかの層に分けて それぞれの役割を明確に区別すること
レイヤー化するメリット 層同士の依存関係が最低限に抑えられるので 層のインターフェースが変わらなければ、他の層への影響はあまりない (ことが多い) つまり、変更がしやすくなる。
たとえば <?php class ApplicationLayer { public function reserve(Reservation $reservation) {
if ( ! $reservation->isReservable()) { // 予約不可な場合の処理 } // 登録処理 } } 予約が可能かどうかのロジックがいくら変わろうが、アプリケーション 層は変更せずにそのまま使用できる
基本的な4つの層 プレゼンテーション層 アプリケーション層 ドメイン層 インフラ層
プレゼンテーション層 アプリケーションの外側と内側の接点 最終的にアプリケーションの外側に渡したいデータを出力する役割を持 っている
アプリケーション層 ドメインロジック以外の処理を担当する
ドメイン層 ドメインのルール・ロジックを全て担当する。 ドメイン層以外はドメインロジックを持ってはいけない
インフラ層 データベースとのやりとりなどを担当する
ドメイン層を構成する要素 Domain Service Entity ValueObject Factory
ValueObject イミュータブル(不変)なオブジェクト 値としてあるべき姿や振る舞いを定義してあげる
たとえば 会議室の予約に通常の予約の他に「仮予約」や「キャンセル」などのス テータスがあった場合、予約のステータスの値には特定の値しか存在し てほしくありません。 そういったときなどにValueObjectを作ります。
Entity ミュータブル(可変)なオブジェクト 1つの1レコードをオブジェクト化するイメージ 複数のValueObjectやリレーション先のEntityなどで構成される 様々なドメインルールを表現する
たとえば キャンセルされた予約は予約済みに戻すことができないというドメイン ルールがあった場合、以下のような感じで表現出来ます <?php class Reservation { protected $status; function
reservedBy(User $user) { if ($this->status->isCancel()) { throw new LogicException(); } $this->user_id = $user->getUserId(); $this->status = new Status('Reserved'); } }
たとえば こういった書き方をすることによって、ドメインルールと矛盾した処理 をアプリケーション層で書くことが不可能になります <?php class ApplicationLayer { public function badReserve()
{ $canceledRsv = $this->rsv_repo->findById($id); $user = $this->user_repo->findById($user_id); // 絶対に例外が発生する $canceledRsv->reservedBy($user); $this->rsv_repo->save($reservation); } }
Factory Entityを生成する際に複雑な処理が必要な時などに使う
Domain Service Entity単体では対応しきれないドメインルールを担当する
たとえば ユーザーのメールアドレスは重複してはならないというドメインルール があった場合 これは複数のEntityに関わることなので1つのEntityだけでは判断しきれ ません。 そういった処理はDomain Serviceの仕事となります。
インフラ層を構成する要素 Aggregate Repository
Aggregate ライフサイクルが同じオブジェクトをひとまとめにする「概念」
たとえば 会議室の予約に、利用者一覧みたいなデータを登録できるとします。 利用者の人数は可変なので予約とは別テーブルにすることにします。 テーブルは別ですが、新規予約時に予約と一緒に利用者も登録されます し、予約の編集時に利用者も編集されますし、予約の削除時に利用者も 削除されるかと思います。 また、予約をどうこうする時以外は利用者のデータは変更されなさそう です。 こういった場合は予約と利用者は一つの集約と言えます。
Repository データベースへのアクセスを提供する役割を持つ。 Aggregateごとに作成して、整合性を保つ。 AggregateのルートになるEntity以外へは直接アクセスさせない。
たとえば 先ほどの例でいうと 予約がAggregateのルートになり、予約Entityからしか利用者のデータに は辿れなくします。 そうすることによって、Aggregate内の整合性を保ちやすくします。
たとえば ルートとなるReservationに利用者は10人までしか登録できないというド メインルールを定義します。 <?php class Reservation { protected $users =
[]; public function addUser(User $user) { if (count($this->users) > 10) { throw new LogicException(); } $this->users[] = $user; } }
たとえば そうすると、もちろんReservationEntityを使う限り10人を超えた利用者 は登録できなくなります <?php class ApplicationLayer { public function badAddUser()
{ // たくさんのユーザー $users = $this->user_repo->getAllUsers(); $reservation = $this->rsv_repo->findById($id); foreach ($users as $user) { // 10 人を越えると必ず例外が発生する $reservation->addUser($user); } $this->rsv_repo->save($reservation); } }
たとえば そして、RepositoryはルートEntityしか受け付けないようにすることで ドメインルールに適合したデータのみがDBへ書き込まれることが保証さ れます。 <?php class ReservationRepository { public function
save(Reservation $reservation) { // DB への書き込み処理 } }
まとめ デザインパターンを駆使して、変更が容易な設計にしよう! 変更を容易にしてモデリングをしまくろう! 良いアプリケーション、作ろうぜ!