これで理解できるドメイン駆動設計!

前書き

このシリーズは1冊の本にできるような分量があります。だったら電子書籍にでもしたらいいじゃないかと言われればそうなのですが、今のところは一般公開することにしています。将来的にはこのページは非公開にしてkindleで電子書籍になっているということもありえます。面倒なので今のところ予定はありませんけども。

想定読者はドメイン駆動設計の初学者から何か本を読んでわかったようなわからないような状態の人です。また、大規模な開発組織は想定していません。エンジニア人数でいえば10人未満、コード量でいえば10万行そこそこの規模までを想定しています。あるいはマイクロサービスやモジュラモノリスがオーバーエンジニアリングに感じられる規模ともいえます。

理屈の話だけではなく実際にどうやっていけばいいのかがわかるという状態を目指しています。また、理屈に凝り固まった理想論ではなく、現実との折り合いをどうつけていくのかという点も重視しています。

ドメイン駆動設計の概要

ここではドメイン駆動設計の概要を説明しています。これらの章を読むことでドメイン駆動設計という手法がいかなるものなのか理解できるはずです。

  • ドメインとは
    • ドメインという言葉はどこからきたのか
    • ドメインという言葉の意味
  • モデル、ドメインモデル、モデリングとは
    • モデルとは何か
    • ドメインモデルとは何か
    • モデリングとは何をする活動なのか
  • ドメイン駆動設計とは
    • ドメイン駆動設計とは何か
    • ドメイン駆動設計は何を達成しようとしているのか
    • ドメイン駆動設計を実践することで何を得ることができるのか
    • コラム:この定義が本当ならなんでこんなに情報が混乱しているの?

ドメイン駆動設計での実装

ドメイン駆動設計の文脈でよく話される設計パターンとレイヤの話について説明しています。なぜドメイン駆動設計の文脈で設計パターンが言及されるのか、レイヤパターンとの関係、各レイヤの役割がなんなのかが理解できるはずです。

  • ドメイン駆動設計の戦術的設計とは
    • なぜドメイン駆動設計に戦術的設計と呼ばれる設計パターン群があるか
    • 設計パターン群の役割
    • 設計パターン群の解説
    • 設計パターン群の依存関係
    • コラム:依存関係の制限は丸暗記すべき?
    • コラム:トランザクションをどこで張るか
    • コラム:ドメインモデルとの対応と依存以外のEntityとValueObjectに関する話は忘れて良い
  • レイヤとドメイン駆動設計の関係
    • レイヤとは
    • ドメイン駆動設計とクリーンアーキテクチャ、オニオンアーキテクチャの関係
    • ドメインレイヤとは
    • インフラストラクチャレイヤとは
    • ユースケースレイヤとは
    • レイヤをまたぐ
    • コラム:TypeScriptの型パズル、クリーンアーキテクチャのレイヤパズル
    • コラム:アーキテクチャと保険

ドメイン駆動設計の核心

多くの人が「戦略的設計がドメイン駆動設計の核心である」と勘違いをしています。ドメイン駆動設計の核心は戦略的設計ではありません。もちろん、戦術的設計でもありません。ではドメイン駆動設計の核心とはなんなのか、それをこれらの章で説明します。

  • ドメイン駆動設計の核心
    • ドメイン駆動設計の核心は何か
      • ユビキタス言語とは何か
      • モデル駆動設計とは何か
      • 実践的モデラとは何か
    • ドメイン駆動設計の核心と戦術的設計
    • ドメイン駆動設計の核心と戦略的設計
  • モデリング手法
    • RDRAとかユースケース駆動開発とか
    • 最近流行りのイベントストーミング
    • 私がおすすめする手法
      • フィーチャーツリー
      • ユースケース(ユーザーストーリー)
      • データモデリング
      • データディクショナリ
      • ビジネスルール
      • 状態遷移図
    • 1つのモデルを使い回すか、ユースケースごとにモデルを考えるか
    • コラム:データモデリング、データディクショナリはRDBのテーブル設計のためのものではない
    • コラム:ApplicationService名にアクターをつけるかつけないか
    • コラム:クラス名のサフィックスをどうするか

ドメイン駆動設計ハンズオン

食品加工業者のECサイトを例にドメイン駆動設計のハンズオンをしていきます。

  • はじめに
  • フィーチャーツリーを作る
    • フィーチャーツリーでドメインを分析して機能構造を明らかにする
    • 境界づけられたコンテキストやパッケージの候補
    • コラム:商品管理は管理グループでは?
  • ユースケースの洗い出し
    • ユースケースによってどのようなユーザー操作があるのか明らかにする
    • ApplicationServiceの候補を明らかにする
    • コラム:フィーチャーツリーの分類とユースケースの分類
  • 管理者が商品を登録する
    • ユースケースと機能要求を元にモデリングする
    • データモデリング
    • 保存のためのAggregateを構築する
    • Aggregate、Entity、Repository
    • コラム:複雑なバリデーションが必要な場合はどうするか
    • コラム:これだけならAggregateもRepositoryもいらないのでは?
    • コラム:ORMのバリデーションとAggregateのバリデーションの使い分け
  • ユーザーが商品を検索する
    • 出力のためのAggregateを構築する
    • CQRS
    • コラム:CQRSって当たり前な気がするけど?
    • コラム:ページネーションのライブラリを使っている場合どうするの?
  • 管理者がセール情報を登録する
    • 機能が割り込みで追加された場合
    • 少し複雑な保存のためのAggregateの構築
  • 「ユーザーが商品を検索する」を再モデリング
    • セールを商品検索に適用する
    • セール機能を追加するために商品検索機能の再モデリングを行う
    • ビジネスルール、データディクショナリ
    • ValueObject、Specification
    • コラム:なぜ全部ValueObjectで置き換えないのか
    • コラム:データモデルのER図にValueObjectなどは反映しないのか
  • ユーザーがショッピングカートに商品を追加する
    • レイヤまたぎ
    • Transaction Script
  • ユーザーがショッピングカートの中身を確認する
    • フィーチャーツリーの見直し
    • ValueObjectとSpecificationの移動
    • ハンズオンのまとめ

落穂拾い

  • 落穂拾い
    • RepositoryはApplicationServiceにDIしなくて良いのか?
    • ValueObjectで間違った値を入れられないようにした方が良いのでは?(DomainPrimetive)
    • ValueObjectのコンストラクタでのバリデーション(Domain Primetive)
    • ***をやった方が良いのでは?
    • ディレクトリ構成をどうするか?
    • ドメインレイヤの依存関係
    • Railsはドメイン駆動設計に向かない?
    • ApplicationServiceから別のApplicationServiceを呼び出すのはありか?
    • コラム:アーキテクト見習い、 一人前のアーキテクト、アーキテクト見習い未満

終章

  • 旅立ち
    • モデリング手法の学習と選択
    • 戦略的設計
    • ドメインイベント
    • イベントソーシング
    • モジュラモノリス、マイクロサービス

付録