"「実践ドメイン駆動設計」から学ぶDDDの実装入門" 10 章感想 (全14章)
"「実践ドメイン駆動設計」から学ぶDDDの実装入門"
「実践ドメイン駆動設計」から学ぶDDDの実装入門 (CodeZine Digital First)
- 作者: 青木淳夫,山田祥寛
- 出版社/メーカー: 翔泳社
- 発売日: 2019/05/31
- メディア: オンデマンド (ペーパーバック)
- この商品を含むブログを見る
「集約」〜トランザクション整合性を保つ境界〜
memo
- 集約(
Aggregates
)とはオブジェクトのまとまりであり、即時に整合性を保ちながらデータを更新する単位
。オブジェクトの集まりの「境界線」の意味で使われる。- 外部からは
集約ルート
となるエンティティを介してのみ操作
可能。(操作をしない外部からの参照だけなら、他の集約からの参照は許可。) - 5つルールと4つの例外がある
- 外部からは
楽観的並行性制御(optimistic concurrency control)
データ取得時時点で一意に識別できる値と更新時点での値の差の有無で更新を制御 <->pessimistic concurrency control
ロックを取って並列更新を制御- 大きすぎる集約はトランザクションの衝突が多くなるため、小さな集約として切り出す。他の集約を参照するにはその集約ルートの一意な識別子のみを参照する。
Global Transaction (::= Distributed Transaction)
の実現手法として2 phase commit
がある。デメテルの法則 (Law of Demeter, LoD)
または最小知識の原則 (Principle of Least Knowledge)
で保守性の向上。 ref. https://ameblo.jp/principia-ca/entry-11876117369.htmlTell-Don't-Ask
(ref. https://martinfowler.com/bliki/TellDontAsk.html) Askしないことで、振る舞いが対象オブジェクトに移動するのを推奨する。Disconnected Domain Model
::= AggregatesからRepositoryを用いて他のAggregatesを読み出す。これよりは Domain Serviceで実現のほうが良い。
分からないこと
- 次の2つのルールは、変更管理を容易にするための方針なのだろうか?
- 単一トランザクションでは単一の集約のみ更新すべき。 <= IDDD原著 http://www.informit.com/articles/article.aspx?p=2020371&seqNum=4 によると
If you are modifying multiple instances in a single transaction, it may be a strong indication that your consistency boundaries are wrong.
- 集約はルートエンティティ以外は値オブジェクトから構成するべき。
- 単一トランザクションでは単一の集約のみ更新すべき。 <= IDDD原著 http://www.informit.com/articles/article.aspx?p=2020371&seqNum=4 によると
"「実践ドメイン駆動設計」から学ぶDDDの実装入門" 9 章感想 (全14章)
"「実践ドメイン駆動設計」から学ぶDDDの実装入門"
「実践ドメイン駆動設計」から学ぶDDDの実装入門 (CodeZine Digital First)
- 作者: 青木淳夫,山田祥寛
- 出版社/メーカー: 翔泳社
- 発売日: 2019/05/31
- メディア: オンデマンド (ペーパーバック)
- この商品を含むブログを見る
「モジュール」〜高凝集で疎結合にまとめる〜
つまり 閉鎖性共通の原則(Common Closure Principle)
.
memo
- IDDDの「モジュール」はJavaではパッケージに相当。依存関係や概念が同じものを一つのモジュールとしてまとめることで、
モジュール間は疎結合となる
。- モジュールは別のモジュールに依存しないようにするべき。
- 意味的にモジュールあいだに双方向の依存がある場合でも、
実装は単一方向の依存とするべき
。
- 意味的にモジュールあいだに双方向の依存がある場合でも、
- モジュールは別のモジュールに依存しないようにするべき。
- プロダクト名でパッケージをつけるよりは、ユビキタス言語である「境界づけられたコンテキスト」でパッケージを命名するほうが、プロダクト名の変更の影響を受けなくてすむ。
分からないこと
domain
やport
というDDDの大きな枠組み配下にクラスは存在させないようだ。これはIDDDのルールなのか?
例: jp.company.<context-A>.domain // <- domain配下にクラスは存在させない。これはIDDDのルールなのか? jp.company.<context-A>.domain.model jp.company.<context-B>.domain jp.company.<context-B>.domain.model.{value-obj,entity,domain-service,domain-event,repository,aggregates}
"「実践ドメイン駆動設計」から学ぶDDDの実装入門" 8 章感想 (全14章)
"「実践ドメイン駆動設計」から学ぶDDDの実装入門"
「実践ドメイン駆動設計」から学ぶDDDの実装入門 (CodeZine Digital First)
- 作者: 青木淳夫,山田祥寛
- 出版社/メーカー: 翔泳社
- 発売日: 2019/05/31
- メディア: オンデマンド (ペーパーバック)
- この商品を含むブログを見る
【ドメインイベント」〜出来事を記録して活用〜
気になった所
- イベントpublishの前に
集約
というキーワードが出てきているが説明が後の章(10章)なのでわかりにくい。 - p.102
分散トランザクションの導入は製品固有の知識が必要ないため
<=むしろ必要では。多分書き間違え。
学んだ事
- ドメインイベント::=
ドメインモデルの一部であり、ドメイン内で発生する何かの出来事
分からないこと
- Domain Eventを用いると、集約の制約(
単一のトランザクションでは単一の集約の塊だけを変更する
という推奨ルール)から開放して結果整合性を保てる。
"「実践ドメイン駆動設計」から学ぶDDDの実装入門" 7 章感想 (全14章)
"「実践ドメイン駆動設計」から学ぶDDDの実装入門"
「実践ドメイン駆動設計」から学ぶDDDの実装入門 (CodeZine Digital First)
- 作者: 青木淳夫,山田祥寛
- 出版社/メーカー: 翔泳社
- 発売日: 2019/05/31
- メディア: オンデマンド (ペーパーバック)
- この商品を含むブログを見る
「ドメインサービス」〜複数のものを扱うビジネスルール〜
メモ
- DDDにおけるサービスには「アプリケーションサービス」と「ドメインサービス」の2つがある。
- セパレートインターフェイス::=実装クラスとは別の
パッケージ
(クラスではない!!)でインタフェースを定義すること。これはDIP
の依存関係を表現していると思う。- 書籍には
複数実装がなく今後実装を差し替える可能性がないなら不要
とあるが DIPの実現はできない気がする、、、
- 書籍には
Correct Diagram.
<domain package> AuthenticationService -> IEncryptionService ------------------------------------------------↑-------- | <infra package> MD5EncryptionService
Incorrect Diagram.(よくやりがち?)
<domain package> AuthenticationService | ----------------------↓--------------------------------- <infra package> IEncryptionService <- MD5EncryptionService
"「実践ドメイン駆動設計」から学ぶDDDの実装入門" 6 章感想 (全14章)
"「実践ドメイン駆動設計」から学ぶDDDの実装入門"
「実践ドメイン駆動設計」から学ぶDDDの実装入門 (CodeZine Digital First)
- 作者: 青木淳夫,山田祥寛
- 出版社/メーカー: 翔泳社
- 発売日: 2019/05/31
- メディア: オンデマンド (ペーパーバック)
- この商品を含むブログを見る
6章:値オブジェクト〜振る舞いを持つ不変オブジェクト〜
学んだ事
値オブジェクトは6つの特徴がある
- 「domain内の知識を計測・定量化・説明している」
- 「immutable」(変更を管理する必要がない)
- 「概念的な統一体」である。(例:100円通貨は2つのパティ「100」と「円」で意味を持つ)
- 「交換可能性」:値を変更したいときは新オブジェクトで交換可(これが不便でエンティティを採用するのはだめ。エンティティは長期に渡って識別する必要があるときのみ使用!)
- 「等価性」:各属性すべてが同じなら等価
- 「副作用のない関数」:呼び出しは如何なるオブジェクトの状態も変えない
他コンテクストエンティティは、粗結合にするために、値オブジェクトとして新たに用意する。
- JPY,USD等、通貨はenumとして良く扱うが、これは
Value Object
ではなく、Standard Type
とVernon氏は呼んでいる。
分からないこと
- テストを書くとき、値オブジェクトで、
自分自身を引数とする
コピーコンストラクタを用意する。 <=不変性
のテストだろうか。イマイチ具体的例を思いつかない。
"「実践ドメイン駆動設計」から学ぶDDDの実装入門" 5章感想 (全14章)
"「実践ドメイン駆動設計」から学ぶDDDの実装入門"
「実践ドメイン駆動設計」から学ぶDDDの実装入門 (CodeZine Digital First)
- 作者: 青木淳夫,山田祥寛
- 出版社/メーカー: 翔泳社
- 発売日: 2019/05/31
- メディア: オンデマンド (ペーパーバック)
- この商品を含むブログを見る
5章 「エンティティ」〜 一意な識別子で同一性を識別
良い所
- みんな何となくやっている実装を言語化してsummarizeするのに役立つかも? (例:ユースケースのシナリオでの「変更」というワードを使用する主語がエンティティ候補になる)
- Software Designの歴史を知れる
悪い所
代理識別子
(システム上のキー)はGoogleのexact matchで調べる限りでは一般的ではなさそう。hibernateのドキュメントを眺めた感じだとidentifier properties
がソースかな?まだ識別子プロパティ
の方が良いかも。
気になった所
- Nothing
学んだ事
- モデルの発展に合わせてユビキタス言語を用語集に反映。
DDD (Domain Driven Development) はオブジェクトモデリングを中心にシステム構築を考える。
自己カプセル化
」::= コンストラクタで、引数のvalidation 機能を持つsetterを介して値を設定する。
Entity
EntityのPropertyのバリデーション
Design By Contract(契約による設計)
/Programming By Contract(契約プログラミング)
::= (Bertrand Meyer氏によるオブジェクト指向入門という書籍で紹介されている考え方。原著は1990年頃発売?)- https://developer.hatenastaff.com/entry/2016/09/01/163542 にあるのがわかりやすい。
関数の仕様を決める時に、関数を実行するのに何が必要か(事前条件)、そしてどういった結果を返してくれるのか(事後条件) をはっきりさせて分析することで、関数の責任や他の部分との
境界を明確にして整理することができます。
さらに、契約に基づいて関数の事前条件や事後条件をコード上に表明(assertion)として表現することで、コードのまちがいに気付きやすくなり、信頼性の高いソフトウェア開発につながります。
- https://developer.hatenastaff.com/entry/2016/09/01/163542 にあるのがわかりやすい。
Entityオブジェクト全体のバリデーション
- 対応するバリデータをクラスで適切なタイミングで行う。 対応するバリデータクラスに対象Entityとinvalid時のhandlerをコンストラクタで渡してvalidateするやり方は考えたことがなかった!
複数個のEntityオブジェクト組み合わせ時のバリデーション
- Domain serviceで制御するらしい。具体例が思いつかないが7章の解説を待とう。
分からないこと
- Nothing
"「実践ドメイン駆動設計」から学ぶDDDの実装入門" 4章感想 (全14章)
"「実践ドメイン駆動設計」から学ぶDDDの実装入門"
「実践ドメイン駆動設計」から学ぶDDDの実装入門 (CodeZine Digital First)
- 作者: 青木淳夫,山田祥寛
- 出版社/メーカー: 翔泳社
- 発売日: 2019/05/31
- メディア: オンデマンド (ペーパーバック)
- この商品を含むブログを見る
良い所
(。・_・。)
アーキテクチャの概要がいっぱい。スンナリ頭に入ってくれば君はアーキテクト!?
共通概念の言語化による共有という観点でココらへんの用語を適切に使えればコミュニケーションが簡便になると思われる。
悪い所
- ESB (Enterprise Service Bus) が何なのか皆目見当がつかなかった (自分の事前知識不足)。 次のリンクをググって理解した。 https://arch.simplicable.com/arch/new/10-soa-design-patterns-every-architect-should-know の4や https://www.ibm.com/developerworks/jp/webservices/library/ws-universalports-esb/index.html 言語化すると次のようになる。
4.11 DDDにおけるCQRSでの流れ
に具体例がほぼないので一読ではよくわからない。例を上げるなら;
気になった所
- 専門用語が一気に出てくるため、よくわからなければ理解を深めるためにググる方が良い。
学んだ事
- SOA (Service Oriented Architecture) は8つの設計原則をもつサービスのアーキテクチャ。
- 昔ながら3層(UI -> Web-Server -> DB-Server) もレイヤ化アーキテクチャの一種。
- DIP (Dipendency Inversion Principle) によりドメイン層が依存されるだけの状態にする。これによりドメインの管理がしやすくなる。
- 「ヘキサゴナルアーキテクチャ」はドメインを中心にとらえ、外部接続インタフェースである「ポート」の部分を差し替え可能である「アダプタ」とする。
- CQRS (Command Query Responsibility Segregation) とは Command実行とQuery実行は別々の処理として分離しなければならないということ。
Command ::= *void* modify(...)
Query ::= *ImmutableType* get(...)
- DDDの観点では「結果整合性」が許容される場合は使用することで複雑性を排除する。
- システムが複数ある場合、イベントを扱うことで複数のシステム間の結合を疎にできる。
- IDDDではイベント駆動のアーキテクチャとして次の3つを紹介している;
- 「パイプ&フィルター」: UNIX コマンドに当てはめるとよい。パイプで分離することにより、再利用性やチューニングをしやすくできる。
- 「長期プロセス(Long-Running processes)」:「並列でパイプラインを実行できる。」 とあるが主目的は、ユーザーからのレスポンスを待つ幾つかのストーリーが逐次実行されて初めて目的が達成されるという意味での正に「長期プロセス」のことである。 ref. https://www.slideshare.net/BerndRuecker/long-running-processes-in-ddd https://github.com/berndruecker/flowing-retail
- 「イベントソーシング」: パターンの一つ。発生したすべてのイベントを「イベントストア」に記録する。「イベントストア」としてはKafka辺りで実現できそう。
分からないこと
知らない概念が多かったので時間がかかった。この後は暫く簡易な概念が続くはず、、、