SYM's Tech Knowledge Index & Creation Records

「INPUT:OUTPUT=1:1以上」を掲げ構築する Tech Knowledge Stack and Index. by SYM@孤軍奮闘する IT Engineer.

DDD 実践メモ

DDD 実践メモ

随時追記

DDDのパッケージ構成

以下が参考になる

Repositoryのinterfaceはdomain層とQueryServiceのinterfaceはapplication層に置く。それによりrepository層の直依存を切れる。repository→application/domain層への依存を最小化できる。関心の分離

リポジトリ

  • NGパターン
    • 1エンティティに対して複数Repository作る -> データ/ロジックの整合性が取れない
      • 対策:状態更新に関わる振る舞いはEntityやServiceに実装
    • 子テーブルにもRepositoryを作成する -> ビジネス要件のチェックロジックがrepositoryにも持たざるを得なくなったり、チェック処理を迂回して更新ができてしまう
      • 対策:集約を使う
    • 複雑なクエリをRepositoryで発行する -> メンテナンスしづらい、かつ N+1問題にもつながりかねない
      • 対策:CQRS

Repository は集約の単位で作成

ref:

集約

  • 永続化の単位となるクラス群。境界の定義
  • トランザクション範囲。(トランザクション整合性)
  • 集約の操作は集約ルートを介してのみ可能
  • 集約は小さくし、トランザクションの範囲は最小限にする。->トランザクションの衝突が少なく、スケーラビリティ/性能が良く保てる
  • 別の集約ルートはIDのみ保持して参照する->値の同時更新が必要ならEntityを持ち、参照のみで済むならID保持(参照するデータが変わるならID変えるだけで済む)

以下に立ち向かう方法が集約:

  • サービスクラスに大量の Repository をインジェクションが必要に…
  • オブジェクトの一部だけをロードして、子要素が NULL の状態に…
  • データアクセスの設定/記述方法により N + 1 問題発生…

例:

orderRepository.save(order);
order.orderDetails.forEach(orderDetailRepository::save);

を、1リポジトリで両方の永続化を行うことで以下となり、コードの複数箇所で Order と OrderDetail 保存する場合にも、1Repository の内部実装にて共通化可能

orderRepository.save(order);

ref:

-

CQRS

  • 部分的導入が可能
  • QuerySerivceの戻り値がユースケースに依存するものなためUseCase層

以下が参考になる

reference indexes