なぱろぐ

日々の色々なアレを残しとく的な

読了: エリック・エヴァンスのドメイン駆動設計

エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)

エリック・エヴァンスのドメイン駆動設計 (IT Architects’Archive ソフトウェア開発の実践)

DDDといえばこれ。読んでくじけちゃうやつ。 実際後半はくじけかけてた、というかきちんと理解できてないけどとりあえず読むだけ読んでみた感じ。

他にDDD関連本読んで基礎知識入れてからでないと前半で撃退されるのでは。

本当ならためになる部分とか自分の理解を書いたほうがいいんだろうけど、これはただの読了メモエントリなのでその辺は省略。IQ低めなざっくり感想と読書中のメモだけ張り付けておく。

目次

全4部の17章構成になっている

  • 第1部 ドメインモデルを機能させる
    • 第1章 知識をかみ砕く
    • 第2章 コミュニケーションと言語の使い方
    • 第3章 モデルと実装を結びつける
  • 第2部 モデル駆動設計の構成要素
    • 第4章 ドメインを隔離する
    • 第5章 ソフトウェアで表現されたモデル
    • 第6章 ドメインオブジェクトのライフサイクル
    • 第7章 言語を使用する:応用例
  • 第3部 より深い洞察へ向かうリファクタリング
  • 第4部 戦略的設計
    • 第14章 モデルの整合性を維持する
    • 第15章 蒸留
    • 第16章 大規模な構造
    • 第17章 戦略をまとめ上げる

まえがきでは2.3.4.9.14章は読むべきである。と案内している。 全部読もうとして挫折するくらいだったら、いったんおすすめされてる章だけ読むだけでもいいと思う。

ざっくり感想

  • 非常にためになる。ためになるがハイカロリー
    • DDDに関心があるならぜひ1度読んでおきたい
    • ただ内容がとても難しい・・・意識を強く持たないと読んでるけど頭に入ってこない状態になりがち
  • 読了後はできればだれかと議論したほうがいい
    • 内容が複雑、多岐にわたることもあって個々人によって解釈や理解度がバラけそう - 読み終わった人同士で本持ち寄って議論できたりするとグッと理解が深まりそう
      • 輪読会なら最大値の効果が得られそうだけど、いかんせん会の継続運営難易度が高い
      • 特定の章に絞るとかならあり?
  • DDD入門で読もうと思ってる人はやめておいたほうがいい
    • 先に数冊DDD関連本読んでから戦うことをお勧めする
  • ある程度読み進めた後に自分のコード振り返ってみたら割と効果が出てた気がする

以下読書中の簡単なメモ

第1章

  • ドメインモデリングはモデルを写実するのではなく映画製作のように現実の概念を表現している
    • 不要な部分は見せない
    • 現実をすべてその通りに再現するのではない
  • モデルの有用性

    • モデルと設計の確信が相互に形成しあう
    • モデルはチームメンバの全員が使用する共通の言語である(ユビキタス言語)
    • モデルは蒸留された知識である
  • 効果的なモデリングの実装

    1. モデルと実装を紐づける
    2. モデルに基づいて言語を洗練させる
    3. 知識豊富なモデルを開発する
    4. モデルを蒸留する
    5. ブレインストーミングと実験を行う

第2章 コミュニケーションと言語の使い方

  • ユビキタス言語
    • ドメインエキスパートとエンジニアによって作成されたモデル(共通言語)
    • 使いにくい、不適切なものがあるときは随時見直さなければならない
    • ユビキタス言語における変更はすなわちモデルに他する変更となる
    • 専門用語が交差するところで高められる
      • 専門的なビジネス用語 -> ドメインエキスパートの領域
      • システム的な専門用語やデザインパターン -> エンジニアの領域
      • 業務用語、構造の用語やパターン名 -> 両方の領域

第3章 モデルと実装を結びつける

モデルと機能の紐づけが複雑だと理解が難しく、設計が変更された時に紐づけを維持できなくなることがある

第Ⅱ部

第4章 ドメインを隔離する

  • レイヤ化アーキテクチャ

    • 原則は「下にある」レイヤにしか依存しないという事
  • ユーザーインターフェース層(もしくはプレゼンテーション層)

    • 人間や別システムのコマンドを解釈
  • アプリケーション層
    • ビジネスに意味があるか別システムのアプリケーション層と相互作用するもの
    • この層は薄く保つ。やるべき作業の調整のみ
  • ドメイン
    • ビジネスの状況の反映を行う
    • その後のデータの永続化(DBへ保存)などはインフラ層
  • インフラストラクチャ層
    • 技術的機能の提供
      • アプリケーション層のメッセージ送信、ドメインの永続化等

第5層 ソフトウェアで表現されたモデル

  • エンティティと値オブジェクトの違い

    • エンティティは同一性を追跡できるもの
  • 値オブジェクト

    • 通販における「住所」
      • 同居人などが複数人が同一住所で注文したとしても、それが「同じ住所」であるかは関係ない
      • つまり同一性を追跡する必要はなく、値オブジェクトとなる
  • エンティティ
    • 電力提供事業者における「住所」
      • 「住居」に対して電気料金が発生する。住居を表す「住所」は同じ住所であれば同一とみなさなければいけない
      • つまり同一性を追跡する必要があり、エンティティとなる

第6層 ドメインオブジェクトのライフサイクル

  • ドメインの集約
    • 例: 自動車
      • 自動車/タイヤ/位置/といったエンティティになる
      • この時自動車エンティティがルートになり、外部からはタイヤを直接参照できない
    • こうして集約することで管理しやすくする
  • ファクトリパターン
    • 本来ドメイン層の責務だが、複雑化したオブジェクトや集約の生成を管理
    • デザパタなどで紹介されている
    • 不変条件をすべて満たすもののみ作成する。満たせない場合は作成不可。例外発生など
    • またファクトリは具象クラスではなく、型に応じて抽象化する
    • コンストラクタではだめなのか?
      • 単純である、かつコンストラクタ内でべつのコンストラクタを呼び出さなければよい
      • 複雑であればファクトリに任せたほうがよい
  • リポジトリパターン

第7層 言語を使用する

  • 集約をどのように分けるか
    • 参照用途などを考慮して経路を考える
    • 貨物 → 荷役イベントの場合は貨物に集約してもよさそうだが、輸送機器側からも参照される
      • その場合は独立すべき
    • リポジトリはそれぞれ集約のルートに対して作成される
  • 腐敗防止層
    • 別のアプリケーションなどと連携するとき、相手側のモデルをそのまま受け入れない
    • こちら側のモデルに変換する「腐敗防止層」を作成して噛ませるのが良い
  • エンタープライズセグメント
    • 理解できていない。あとから解説があるか?

第Ⅲ部

第9章 暗黙的な概念を明示的にする

  • オブジェクトの制約はそれ単品でモデル化した方がいい場合もある
  • 検索などでドメインにあるルールをクエリに適応しないと行けない場合はどうするべきか
    • リポジトリに汎用的なクエリビルダを設置して使用するのが良い

第10章 しなやかな設計

  • 意図の明確なインターフェイス
    • カプセル化しても別の人間が使うときに中身を見なければ理解できないのはだめ
  • 副作用のない関数
    • 既存オブジェクトには影響を与えず、新規オブジェクトを生成など
  • 表明
    • 事前条件や不変条件などを明確にコード化。テスト書いたり
  • 概念の輪郭
    • 読み直し
  • 独立したクラス
    • 依存関係が多くなればなるほど設計を理解する処理の負荷は大きくなる。クラス内の依存関係を可能な限り取り除き、プリミティブを使用することで単独で理解できるクラスになる
    • ただなんでもかんでもプリミティブにすればいいものではない
  • 閉じた操作
    • 戻り値と引数の型が同じであればそれはそのインスタンス集合の中で閉じていると言える

第11章 アナリシスパターンを適用する

  • アナリシスパターンはビジネスモデリングにおける共通の構造、概念のグループ。ドメイン一つの場合もあればまたぐこともある
  • 同一性によって定義されるオブジェクト=エンティティ
    • 例: 同日同金額同口座への振込=区別する必要があるエンティティ
    • 例: その取引の金額オブジェクト=区別する必要はない。エンティティではない
  • アナリシスパターンちゃんと調べる

第12章 デザインパターンをモデルに関係づける

  • ストラテジーパターンとは
    • デザインパターンをモデルに適応する場合はレイヤーを一つ増やす
    • 適応するパターンの考え方がドメインの概念に合うかを確認すること

第13章 より深い洞察へ向かうリファクタリング

  • ドメインに馴染む
  • 常に違う見方をする
  • ドメインエキスパートとの対話を途切れさせない

第Ⅳ部

第14章 モデルの整合性を維持する

  • モデルには統一性が必要
    • ただし巨大なシステムにおいてドメインモデルを完全に統一するこのとは現実的ではないし、コストに見合わない
    • これを無理にやろうとすると次のようなリスクがある
      1. 一度に多くのレガシーシステムを置き換えてしまうかもしれない
      2. 調整にかかるオーバーヘッドが限界を超えてしまうかもしれない。巨大なプロジェクトは身動きが取れない
      3. 特殊な要件の場合は要求を満たさないモデルを使うことになるかもしれない
      4. 単一モデルでどうにかしようとすると複雑になり使いづらい
  • モデルが適応されるコンテキストを明示的に定義すること
  • 境界はチーム編成、アプリケーションの特殊な用途、コードベースやスキーマ定義などの視点から行うこと
  • 偽同族語
    • 同じ言葉でも若干意味が違う
  • 腐敗防止層
    • レガシーなシステムの遺産を使わざるを得ない時に汚染されないためのレイヤー
    • ファサード、アダプタ、変換サービスで構成
    • ファサードが外部を直接操作。アダプタがメインシステムとの橋渡し。変換サービスが必要に応じて形式を変換

第15章 蒸留

  • リファクタリングする時どうするか
  • 全部ダメだからどこからやってもいい、はトッププログラマだけの集団でないと難しい、困ったところから、だと対処療法でしかない
  • 困った時にコアに関連するものであれば頑張って対応する。余裕があるときはコアの適切な抽出、サブドメインからの不純物除去がよい

第16章 大規模な構造

メモ消えてた

第17章 戦略をまとめ上げる

戦略的意思決定を行うために大事なこと

  • 意思決定はチーム全体に伝えなければならない
  • 意思決定プロセスはフィードバックを吸収しなければならない
  • 計画は進化を許容しなければならない
  • アーキテクチャチームが最も優秀な人材をすべて吸い上げてはならない
  • 戦略的設計にはミニマリズムと謙虚さが必要である
  • オブジェクトはスペシャリストだが開発者はジェネラリストである