Slide 1

Slide 1 text

DDDの勉強をしたので5分でまとめる

Slide 2

Slide 2 text

自己紹介 吉田です Twitter @strtyuu

Slide 3

Slide 3 text

ドメイン駆動設計とは? ドメインを モデリングして モデリングして モデリングし続ける設計手法のこと

Slide 4

Slide 4 text

ドメインとは? アプリケーションが解決したい問題そのもののこと

Slide 5

Slide 5 text

モデリングとは? モデルの振る舞いを定義していく作業のことを指します。

Slide 6

Slide 6 text

モデルとは? ドメインを構成する様々な要素のこと

Slide 7

Slide 7 text

たとえば 会議室の予約システムを作りますとなった場合 会議室はもちろんモデルになると思いますし 予約という概念もモデルになります。

Slide 8

Slide 8 text

モデリングのやり方 ドメインエキスパートとドメインについて話し合って 話し合いを設計に反映させて 設計を元に実装をして ドメインエキスパートとドメインについて話し合って 話し合いを設計に反映させて 設計を元に実装をして ドメインエキスパートと...

Slide 9

Slide 9 text

以下エンドレス

Slide 10

Slide 10 text

モデルがどんどん更新されてゆく 実装は更新されてゆくモデルについていかなければならない つまり、変更に対して柔軟な実装になっていないと、 ドメイン駆動設計っていうのは、実現できない

Slide 11

Slide 11 text

柔軟な実装をするために デザインパターンを駆使して、複雑さに立ち向かう Repository Entity ValueObject Layered Architecture Aggregate 他

Slide 12

Slide 12 text

レイヤードアーキテクチャ アプリケーションをいくつかの層に分けて それぞれの役割を明確に区別すること

Slide 13

Slide 13 text

レイヤー化するメリット 層同士の依存関係が最低限に抑えられるので 層のインターフェースが変わらなければ、他の層への影響はあまりない (ことが多い) つまり、変更がしやすくなる。

Slide 14

Slide 14 text

たとえば isReservable()) { // 予約不可な場合の処理 } // 登録処理 } } 予約が可能かどうかのロジックがいくら変わろうが、アプリケーション 層は変更せずにそのまま使用できる

Slide 15

Slide 15 text

基本的な4つの層 プレゼンテーション層 アプリケーション層 ドメイン層 インフラ層

Slide 16

Slide 16 text

プレゼンテーション層 アプリケーションの外側と内側の接点 最終的にアプリケーションの外側に渡したいデータを出力する役割を持 っている

Slide 17

Slide 17 text

アプリケーション層 ドメインロジック以外の処理を担当する

Slide 18

Slide 18 text

ドメイン層 ドメインのルール・ロジックを全て担当する。 ドメイン層以外はドメインロジックを持ってはいけない

Slide 19

Slide 19 text

インフラ層 データベースとのやりとりなどを担当する

Slide 20

Slide 20 text

ドメイン層を構成する要素 Domain Service Entity ValueObject Factory

Slide 21

Slide 21 text

ValueObject イミュータブル(不変)なオブジェクト 値としてあるべき姿や振る舞いを定義してあげる

Slide 22

Slide 22 text

たとえば 会議室の予約に通常の予約の他に「仮予約」や「キャンセル」などのス テータスがあった場合、予約のステータスの値には特定の値しか存在し てほしくありません。 そういったときなどにValueObjectを作ります。

Slide 23

Slide 23 text

Entity ミュータブル(可変)なオブジェクト 1つの1レコードをオブジェクト化するイメージ 複数のValueObjectやリレーション先のEntityなどで構成される 様々なドメインルールを表現する

Slide 24

Slide 24 text

たとえば キャンセルされた予約は予約済みに戻すことができないというドメイン ルールがあった場合、以下のような感じで表現出来ます status->isCancel()) { throw new LogicException(); } $this->user_id = $user->getUserId(); $this->status = new Status('Reserved'); } }

Slide 25

Slide 25 text

たとえば こういった書き方をすることによって、ドメインルールと矛盾した処理 をアプリケーション層で書くことが不可能になります rsv_repo->findById($id); $user = $this->user_repo->findById($user_id); // 絶対に例外が発生する $canceledRsv->reservedBy($user); $this->rsv_repo->save($reservation); } }

Slide 26

Slide 26 text

Factory Entityを生成する際に複雑な処理が必要な時などに使う

Slide 27

Slide 27 text

Domain Service Entity単体では対応しきれないドメインルールを担当する

Slide 28

Slide 28 text

たとえば ユーザーのメールアドレスは重複してはならないというドメインルール があった場合 これは複数のEntityに関わることなので1つのEntityだけでは判断しきれ ません。 そういった処理はDomain Serviceの仕事となります。

Slide 29

Slide 29 text

インフラ層を構成する要素 Aggregate Repository

Slide 30

Slide 30 text

Aggregate ライフサイクルが同じオブジェクトをひとまとめにする「概念」

Slide 31

Slide 31 text

たとえば 会議室の予約に、利用者一覧みたいなデータを登録できるとします。 利用者の人数は可変なので予約とは別テーブルにすることにします。 テーブルは別ですが、新規予約時に予約と一緒に利用者も登録されます し、予約の編集時に利用者も編集されますし、予約の削除時に利用者も 削除されるかと思います。 また、予約をどうこうする時以外は利用者のデータは変更されなさそう です。 こういった場合は予約と利用者は一つの集約と言えます。

Slide 32

Slide 32 text

Repository データベースへのアクセスを提供する役割を持つ。 Aggregateごとに作成して、整合性を保つ。 AggregateのルートになるEntity以外へは直接アクセスさせない。

Slide 33

Slide 33 text

たとえば 先ほどの例でいうと 予約がAggregateのルートになり、予約Entityからしか利用者のデータに は辿れなくします。 そうすることによって、Aggregate内の整合性を保ちやすくします。

Slide 34

Slide 34 text

たとえば ルートとなるReservationに利用者は10人までしか登録できないというド メインルールを定義します。 users) > 10) { throw new LogicException(); } $this->users[] = $user; } }

Slide 35

Slide 35 text

たとえば そうすると、もちろんReservationEntityを使う限り10人を超えた利用者 は登録できなくなります user_repo->getAllUsers(); $reservation = $this->rsv_repo->findById($id); foreach ($users as $user) { // 10 人を越えると必ず例外が発生する $reservation->addUser($user); } $this->rsv_repo->save($reservation); } }

Slide 36

Slide 36 text

たとえば そして、RepositoryはルートEntityしか受け付けないようにすることで ドメインルールに適合したデータのみがDBへ書き込まれることが保証さ れます。

Slide 37

Slide 37 text

まとめ デザインパターンを駆使して、変更が容易な設計にしよう! 変更を容易にしてモデリングをしまくろう! 良いアプリケーション、作ろうぜ!