FLINTERS Engineer's Blog

FLINTERSのエンジニアによる技術ブログ

エリック・エヴァンスのドメイン駆動設計 読書メモ4

元記事はこちら

読書メモ3 の続き。 引き続き第14章を読みました。

第4部 戦略的設計

システムの複雑さがました場合、全詳細を把握することなくモデルを把握するためのテクニックが必要だ。 コンテキスト、蒸留、大規模な構造をみていく。

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

異なるモデルを持つチーム間で実装を共有すると不整合が発生して死ぬ。 モデルが整合性を維持することは重要だ。しかし、巨大なシステムではひとつの整合したモデルを作ることは現実的ではない。調整で動きが取れなくなったり、一部の人にはぎこちないモデルになったりといった問題が出て来る。

代わりに、部分的に統一したモデルを作成する。 ここは統一すべきという意思決定、ここは統一しないでおいたほうが良さそうだという現状認識を共有することで、システムの全体を捉えることができる。 モデル間の境界と関係性を明らかにする必要がある。

境界づけられたコンテキスト

モデルが適用できる範囲のことをコンテキストと呼ぶ。境界によって区切られるので境界づけられたコンテキスト(bounded context)と呼ばれる。 境界づけられたコンテキストの中に複数のモジュールを構成するのが一般的だ。

境界を認識することが第一歩。 モデルが違えばコンテキスト外。モデルによって駆動されているもの(例: DBスキーマ)はコンテキスト内。

コンテキスト内では1つのモデルを使う。 コンテキスト外をそれと認識せず、モデルをなんとなく共有することにはリスクがある。

モデルが混じっていることを認識する方法。

  • 同じ概念が2つの別言葉で話される
  • 同じ言葉が2つの別概念を表す
  • コード上でインタフェースが組み合わせられない
  • コードが予期していない振る舞いをする

混じっていると気づいたら対策が必要になる。

継続的な統合

コンテキスト内でモデルの分裂を頻繁に統合することを継続的な統合と呼ぶ。 モデル概念と実装の両面で統合が必要だ。 モデル概念の統合はメンバ間での絶え間ないコミュニケーションにより達成する。 実装の統合はCI、自動テスト、ブランチマージまでの時間上限を決めるなどで達成する。

コンテキストマップ

モデルや設計は組織構成に影響を受ける。会話をする人同士はコンテキストを共有するようになる。

境界づけられたコンテキストそれぞれに名前を付け、コンテキスト間の関係と、コンテキストが持つ各モデル間の対応関係を記載したものをコンテキストマップと呼ぶ。 コンテキストマップは現状を把握するためのものであり、ありのままの状況を記載することが重要だ。 コンテキストマップには特定の文書フォーマットは無い。

モデルをまたいで対応するオブジェクト間を変換するサービスが境界に存在する。

コンテキストマップをドキュメント化する際に重要なのは次の2点。

  • 境界づけられたコンテキストに名前をつけること。その名前を各チームのユビキタス言語に加える。
  • 境界を全員が認識できること。任意のコード辺が属するコンテキストを認識できなければならない。

境界づけられたコンテキスト間の関係

コンテキスト間関係のうち最も一般的で重要なケースは次の通り。

  • 共有カーネル
    • コンテキスト間で共有するモデルのサブセットを指定する
    • モデル及びモデルに付随するコード、DBなどは変更時にチーム間の相談を経なければならない
  • 顧客/供給者の開発チーム
    • 利用が単方向であるとき
    • チーム間の政治的関係によっては動きが取りづらくなることがある。顧客側チームの代表が供給者側のプラニングに参加させることで、対話によって解決を目指すことができる。
    • 自動化された受け入れテストを共同で開発し、供給者側のCIで実行する
  • 順応者
    • 自分が顧客側であり、供給者側にアクセス出来ない場合に、供給者側のモデルに隷属するパターン
  • 腐敗防止層
    • 出来が良くない他コンテキストと統合したい場合、概念モデル間を変換する層を設けるパターン
    • 使えるデザインパターンとしてファサードとアダプタがある
    • 接続相手のリファクタリング、自モデルの歩み寄りにより、腐敗防止層の複雑さを低減することを検討する
  • 公開ホストサービス
    • 人気のあるコンテキストを対象に、アクセスするプロトコルを公開するパターン
  • 公表された言語
    • 複数コンテキストの接点で変換するときに、変換用に作り出す言語のこと
    • 関心のあるコミュニティが自由にアクセスできる状態にする(公表)

コンテキストマップの変更戦略

現状のコンテキストマップからはじめ、現実的な選択をすること

大きいコンテキスト、小さいコンテキストそれぞれに利点と欠点がある。バランスを取ること。

外部システムを位置づけるときは次のいずれかになる。

  • 統合しない(別々の道)
  • 順応者から腐敗防止層のグラデーションのどこかで統合する

設計中のシステムではコンテキスト境界の引き方に裁量が大きい。 一般的に境界づけられたコンテキスト1つに対して1チームが対応する。複数のチームが1つの境界づけられたコンテキストに取り組むのは難しい。

様々なグループが異なる言葉を使っているとき、モデルを統合するか、別モデルとして扱うかという悩みがある。そのグループの用語にどれほどの価値があるのかを問うことでヒントになることがある。

デプロイ計画は境界の引き方とコンテキスト間関係にフィードバックされるべき。

コミュニケーション意欲や能力、システム全体に対するコントロールによって、適したコンテキスト間関係は異なる。

感想

14章は内容が多い。4部を一回で終わらせるつもりだったが14章だけでお腹がいっぱいになってしまった。 ざっくり言えば、モデルの整合性を保つために、そのモデルが通用する境界を設定してうまくやろうという話。

コンテキスト間関連を明らかにし、関係パターンを適切に選ぶことが、整合性に寄与する。境界の引き方や、パターンの選択にはチームの構成、チーム間関係(力関係を含む)が影響を及ぼすという点は興味深い。設計や実装を中心におき、チームやその関係を適切な形に調整することを私は考えてしまうことが多い。しかし反対に組織構造が設計・実装に与える影響があるということを示唆している。境界の引き方については、むしろ既存の組織構造を反映することを勧めているように聞こえる。

端的にいえば、隣の席にいるのとオフィスの端と端にいるのとで、適切な設計が変わってくるってこと。リモートワークだったらまた変わってくるのだろう。仕事の会話を行う量がポイントなので、仲の良さ(?)なんてのも影響するかもしれない。