第二回ボトムアップドメイン駆動設計
https://ddd-community-jp.connpass.com/event/107106/
行きました!
雑多な感想。
値オブジェクト、エンティティ辺りは最低限理解したい。
メモにある、不変等の定義をよく見ておこう。
それ以外は、自分の今のプロジェクトに近いものがあると思った。
レイヤードアーキテクチャ、今の私の実装と合わせて、自分のプログラムと照らし合わせよう。
あと、DDDを完璧に理解しなくても、細かなテクニックを学ぶことだけでも出来そうだった。ただ、一番は本読むことだな……あくまで、今回の話は本の入門。
てか、この実装の話知らずに本読むのやっぱりむずくない!?
Twitterまとめ
今日参加の勉強会はこれ!
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
■第二回ボトムアップドメイン駆動設計https://t.co/IU5Ze1WJu2
■ハッシュタグ#bu_ddd
あれ?目次増えてない!?#bu_ddd
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
話者『理解した方いますか?』
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
会場『・・・・・』
話者『俺だけですね!』#bu_ddd
■用語
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
マインド
パターン
に大別できる。
マインドは感じるしかないが、
パターンは実装できるよね。
用語と実装が理解出来たら、理解しやすいのでは!?#bu_ddd
■値オブジェクト
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
『値 #とは』
```
num = 1;
num = 2;
```
値の変更は代入。
1.changeTO(2);とか書かないね。
値を示すオブジェクトも値らしくしよう#bu_ddd
1.状態不変
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
2.比較可能
3.完全交換可能#bu_ddd
```
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
var fullname = new fullname('taro', 'yamada');
fullname.changeFamilyName('sato');
```
これがだめなら、
```
var fullname = new fullname('taro', 'yamada');
fullname = new fullname('taro', 'taro');
```
っていう話#bu_ddd
これが状態不変#bu_ddd https://t.co/E7hbhmdsHP
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
不変以外追いつけなかった(((#bu_ddd
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
1.表現力が増す
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
2.ありえない数値を存在させない。
3.誤った代入をさせない
2. intに虚数を入れるとか?
3.
__construct($id) {
$this->id = $id
}
この$idにnameが投げるとか困るけど
__construct(ValueObject $vo)
これでいいよね#bu_ddd
■エンティティ
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
値オブジェクトの逆?
1.可変
2.同じ属性でも区別される
3.同一性をもつ#bu_ddd
■エンティティ
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
1.可変
2.同じ属性でも区別される
3.同一性をもつ
1. (new User('tanaka')).changeName('sato');
2. 同姓同名だけど、別オブジェクトだよね。識別子とか持とうか。
3. tanakaさんがsatoさんに切り替わっても、同一人物だよね。#bu_ddd
ライフサイクル持ってる
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
それはエンティティ。#bu_ddd
■ドメインサービス
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
・重複チェック専用オブジェクトとか、エンティティに実装しない
→こういうのをやるのがドメインサービス
■私的感想
静的呼び出しするか、シングルトンで実装したほうが良さげ・・・?#bu_ddd
話者『リポジトリご存知の方いますか?』
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
会場『めっちゃ手上げる』
話者『なんでここに来たんですか?』#bu_ddd
■リポジトリ
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
エンティティを永続化するのがリポジトリ
■私的感想
ドメインサービス→サービス
リポジトリ→リポジトリ
あ、これうちの開発か。#bu_ddd
テスト好きな方は私と話合いますねという話題から、会場で結構首振ってる人がいる・・・w#bu_ddd
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
■アプリケーションサービス
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
ビジネスロジックのAPI
ユースケースを表現する
エンティティ・値オブジェクト・ドメインサービス・リポジトリ
をいい感じに使って、ユースケースを表現する。
■私的感想
コントローラーかな?
コントローラーのメソッドのことかな?#bu_ddd
アプリケーションサービス
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
→インターフェイスを用意することがある
→セパレートインターフェイス
例外を起こすような整合性のあるデータを渡すのが大変
→例外を投げるやつ作ろう
■私的感想
アプリケーションサービスは、Laravelで書いたコントローラーの関数よりサービスの方なのかな?#bu_ddd
コントローラー
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
→フロント都合の値の形式を、値を加工
→アプリケーションサービスを呼ぶために
アプリケーションサービス、何処まで意味をもたせていいのかな。#bu_ddd
私、
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
コントローラー→サービス→リポジトリ
の3層だったから、私の開発はちょっと層が足りてない感?#bu_ddd
質問するためにいろいろ考えまとめておりますううう
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
拾ってくださり、ありがとうございます!#bu_ddd
会員登録をする。
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
■ユーザーのデータを保存する
・バリデーション引っかかったらメール送らない
・データを保存して、仮パスワード発行
■会員登録完了メールを送る
・完了メール
・仮パスワードメール
その2つを行うなら、どんな振り分けになるんだろう……?#bu_ddd
ユースケースとアプリケーションサービスは一対一のイメージ!
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
なので、会員登録というアプリケーションサービスで、その中でさっきの2つが動く感じ。#bu_ddd
■ファクトリ
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
GoF関係ないよ
ユーザーがユーザーの作り方を知ってるのはおかしい!
生成処理のカプセル化。#bu_ddd
■トランザクション
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
同時ユーザー登録で、ID重複とかなるよ(*´・ω・)(・ω・`*)ネー
ユニークキー成約
→重複チェックいらなくない?
→消したら何が起こってるかわからなくない?
トランザクションスコープ
→そこの間は整合性が必要なのが伝わる
→AOP
→ユニットオブワーク
try catch#bu_ddd
■私的感想
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
try
トランザクション
catch
ロールバック
同じ接続、オブジェクト扱えば整合性が。
サークルにファクトリとユーザー→ユーザーにサークル作成の依頼をする→ユーザーが作る#bu_ddd
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
ユーザーにgetしない。ユーザーが作るから。#bu_ddd
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
ゲッター使うと、サークルの最大人数という条件比較を、外に持って行ってしまう。情報が外にあるから。
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
普通、最大人数とかはサークルにjoin関数作って、そこの中でif文作れば、情報はサークルクラスに含まれるよね。
デメテルの法則
->が2個あるとかないよね!#bu_ddd
集約辺りからついていけなくなりました。(((#bu_ddd
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
リポジトリは集約毎に作成することになる
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
サークルの中にあるユーザーオブジェクトが変更されたら……?
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
→識別子を保存すればいいよね#bu_ddd
タグ読んでると、話が来てないときに先の話のつぶやきが来るのがよくあって、
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
私大丈夫かな、過去に生きてるのかなと思った。
ああ、スライド配布してるから、先読みしてるのね……w#bu_ddd
Scala最強説
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
:thinking_face:#bu_ddd
■ディレクトリ構成のイメージ
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
domain
-app-アプリケーションサービス
-model-user
-model-circle
app-フロントの人が見て理解
model-ろじっくいろいろ。#bu_ddd
ドメイン駆動
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
レイヤード
ヘキサゴナル
クリーン
レイヤード
— ういろう🍤👩🍤@新卒3年目PHPer (@nyamucoro) 2018年12月4日
→プレゼンテーション(コントローラー)
→アプリケーション(サービス)
→ドメイン
→インフラストラクチャ(リポジトリ)