「ドメイン駆動設計をはじめよう」という本を読み始めた
第一部に続いて、第二部の「実装方法の選択」について読書メモを書いておく
第一部の読書メモ
uga-box.hatenablog.com
実装方法の選択
この第二部は、第一部で説明された設計の基本方針をどのように実装するかの話になる
各章の見出しは以下
- 単純な業務ロジックを実装する
- 複雑な業務ロジックに立ち向かう
- 時間軸でモデルを作る
- 技術方式
- 通信
1. 単純な業務ロジックを実装する
中核ではない、一般や補完的な業務領域は更新がバンバン行われるような複雑なものでないことが多い
ここで使うべきアーキテクチャは以下
トランザクションスクリプトは単純なETLのような問題領域の実装に適していて、アクティブレコードはCRUD操作と入力値精査のようなもう少し凝ったことをやりたい場合に適している
とはいえどちらも簡単な業務ロジックに適している
2. 複雑な業務ロジックに立ち向かう
複雑な業務ロジックを扱うにはドメインモデルが適している
事業活動のモデルをソースコードと関連づける手法
実装方針
- 業務ロジックは本質的に複雑なので、不要な複雑さを持ち込まないようにする
- ライブラリやフレームワークに依存させない
- 区切られた文脈の同じ言葉を対応させる
ドメインモデルをやる上どの要素として
- 値オブジェクト
- 集約
- 業務サービス
がある
3. 時間軸でモデルを作る
複雑な業務ロジックで尚且つ、処理の追跡や行動分析が必要な場合に、イベントソーシングを使って集約の状態を管理する方法
イベントソーシングは「イベントを真実を語る唯一の情報源(ソース)」にすること
集約のライフサイクルを業務イベントでモデル化し、集約のすべての状態変更を業務イベントで表現することが必要
実装方針では コマンドクエリ責任分離(CQRS)を使う
利点は以下
- 業務イベントの履歴から、過去の状態が再現できる
- 業務イベントの履歴から、業務活動について洞察ができる
- 業務イベントの履歴から、監査ログとして利用できる
- 従来の楽観的排他制御よりも柔軟な排他制御が可能になる
欠点は以下
- データ管理が初学者には難しい
- データ構造を変えたい場合に難しい
- CQRSが難しい
4. 技術方式
業務ロジックは何よりも重要だが、ソフトウェアの唯一のコンポーネントではなく、永続化したり、入力や出力としてのUIや、外部連携周りなどさまざまなコンポーネントがある
これらをどう構造化するかの話
レイヤードアーキテクチャ
レイヤードアーキテクチャはコードベースを階層構造で整理する手法
3層というのは【プレゼンテーション層】 → 【業務ロジック層】 → 【データアクセス層】 のことで、古典的なアーキテクチャとして広く知られている
4層はこの【プレゼンテーション層】と【業務ロジック層】 の間に【サービス層】を設けて、業務ロジック層の振る舞いをカプセル化して、プレゼンテーション層に公開するインターフェースを定義するようにする手法
ポートとアダプター
レイヤードアーキテクチャは業務ロジックがデータアクセスに依存しているため、ドメインモデルに適していない
そこで、プレゼンテーション層もデータアクセス層もどちらも外部コンポーネントとの連携と考えて、まとめてインフラストラクチャ層として、インフラストラクチャ層の方を業務ロジックに依存させるようにする(依存関係逆転の法則)
そして、【業務ロジック層】 ← 【データアクセス層】の間に【アプリケーション層】を設ける手法(先述した【サービス層】と同様の考え)
業務ロジック層で、インフラストラクチャ層で実装すべきインターフェースを用意する
これを「ポート」と呼び、それを「アダプター」として実装する
ヘキサゴナルアーキテクチャやオニオンアーキテクチャ、クリーンアーキテクチャと呼ばれたりする
他の用語も出典によってはブレていたりするが意味は一緒
- プレゼンテーション層 = ユーザーインターフェース層
- サービス層 = アプリケーション層 = ユースケース層
- 業務ロジック層 = ドメイン層 = モデル層 = コア層
- データアクセス層 = インフラストラクチャ層
CQRS
モデルの責任を、状態変更と読み取りの2つに分離する手法