はじめに
アーキテクチャ設計における「共通化」は、扱い方によって効果が大きく変わる。共通化は重複を減らし保守性を高める手段として有効だが、何でもまとめればよいわけではない。特にドメインロジックの共通化は、一時的に美しく見えるコードベースを、数年後には解きほぐしにくい負債へと変えてしまうことがある。
本稿では、「共通化してよいもの」と「共通化すべきでないもの」の非対称性を、境界づけられたコンテキスト(Bounded Context)の観点から整理する。
なお、本稿で扱うのはマイクロサービスに特有の話ではない。物理的な分割(サービス分割)ではなく論理的な境界の問題であり、モジュラモノリスやパッケージ分割でも同じ罠が起きる。
1. 共通化しやすいもの:技術的関心事
共通化が比較的安全に効く領域として、技術的関心事(technical concerns) がある。具体的には以下のようなものだ。
- ロギング
- メトリクス収集、分散トレーシング
- HTTP基盤
- エラー通知
- 設定読み込み
これらは以下の性質を持つ。
- ビジネスの意味を直接には持たない
- 変更の駆動要因が基盤側にある:ライブラリのバージョンアップ、SREの運用要求など
- 文脈ごとに振る舞いを変える必要がほとんどない:複数の業務文脈から使われても中身は共通でよい
横断的関心事(cross-cutting concern)として切り出し、共通ライブラリや基盤サービスとして独立に進化させるのが合理的である。ここで重複を必要以上に許容すると、かえって全体の保守性を下げてしまうことが多い。
2. グレーゾーン:技術的関心事にドメインが染み出すとき
ただし、「技術的関心事」と一括りにしてしまうと少し大雑把である。純粋に技術的な部分と、ドメイン知識が染み出している部分を区別しないと、別の形の罠を踏む。
認証と認可
- 認証(誰であるかを検証する):技術基盤として共通化しやすい領域
- 認可(その人が何をしてよいかを判定する):ドメインルールの塊
「販売担当者は自部門の注文のみ参照できる」「与信担当者は承認フロー中の案件のみ閲覧できる」といった業務要件は、認可ポリシーそのものである。これらをまとめて「認証認可ライブラリ」に押し込むと、ドメイン変更のたびに基盤側を触ることになり、基盤の変更速度と業務要件の変更速度に不整合が生まれる。
ロギング
- フォーマットや出力先:共通化してよい領域
- どの項目を個人情報として伏せるか、どのイベントを監査ログとして永続化するか:ドメイン知識に基づく判断
共通ロガーはフォーマットと出力先だけを受け持ち、何をどう扱うかの判断はドメイン側に残すのが安全である。
技術的関心事は積極的に共通化してよいが、その中に紛れ込んでいるドメイン判断を見逃さないことが重要になる。
3. 共通化してはいけないもの:ドメインロジック
本稿で最も強調したいのはここである。特定のドメインに属するロジックの共通化は、アーキテクチャ上の大きな罠になる。
「顧客」「注文」「価格」のように、複数のサブシステムに同じ名前のモデルが登場することは珍しくない。構造も一見似て見える。しかし、共通のモデルや共通のサービスにまとめると、時間が経つほど綻びを生みやすくなる。
DDDの言葉を借りれば、同じ言葉であっても境界づけられたコンテキストが異なれば別物である。
- 販売ドメインの「顧客」:購買履歴と配送先を持ったエンティティ
- 与信ドメインの「顧客」:信用スコアと審査状態を持ったエンティティ
- マーケティングの「顧客」:セグメントとキャンペーン応答履歴を持つエンティティ
名前と識別子が同じだけで、不変条件もライフサイクルも、変更の駆動要因も異なる。
4. なぜドメイン共通化が罠になるのか
ドメインロジックを無理に共通化すると、以下のような力学が働く。
文脈ごとの不変条件の衝突
ある文脈で必須な属性が、別の文脈では不要になることがある。ある文脈で許される状態遷移が、別の文脈では禁止されることもある。共通モデルにまとめた場合、すべての文脈で最も厳しい制約に従うか、フラグと分岐で塗り固めるかの二択に追い込まれる。
変更速度の律速
共通化されたコンポーネントは、最も慎重に扱われる文脈の変更速度に引きずられる。本来なら独立に進化できたはずのドメインが、互いに足を引っ張り合う関係になる。
所有者の消失
Shared Kernel 的(複数のコンテキストが同じドメインモデルを共有所有する DDD のパターン)に共有されたドメインコードは、複数チームのどこにも完全には属さない。誰もが触れるものの、責任の所在が曖昧になりやすい状態に陥る。コンウェイの法則(Conway's Law)の観点からも、組織境界を越えたコードは摩擦を生みやすい。
剥がすコストの肥大化
一度「共通ドメインモデル」として定着すると、それを前提に多くのコードが書かれていく。後から文脈ごとに分離しようとすると、データ移行・API互換・テスト・チーム間の合意のすべてが絡む巨大な作業になる。
5. 共通化を見分けるための問い
共通化の是非を判断する際には、以下の問いが有効である。
- 変更理由はどこにあるか:基盤都合(ライブラリ、運用、セキュリティ)か、ドメイン都合(業務ルール、商習慣)か
- 所有者は同じか:コードを所有し変更判断を下すチームと文脈は単一か
- 将来、文脈ごとに別の進化を遂げる可能性はあるか:今は同じに見えても業務要件の変化で分岐する余地があるなら、共通化は将来の足枷になりやすい
「コードの形が似ている」ことは、共通化の十分条件にはならない。似ているのが偶然なのか本質なのかを問う必要がある。
6. 常に分離が正義とは限らない
ここまでドメイン共通化の危険について述べてきたが、どんな状況でも分離すべきだと言いたいわけではない。
プロダクトの初期フェーズや小さなモノリスにおいて、将来の境界づけられたコンテキストを予測して過剰に分離するのは、別種の罠になる。ドメインの輪郭がまだ定まっていない段階では、一つの場所で進化させて、境界が見えてから切り出す方が安全なことが多い。
重要なのは、「分離する/しない」を一度決めたら終わりにせず、組織規模・プロダクトフェーズ・ドメインの成熟度に応じて見直し続ける姿勢である。
おわりに
共通化は一見すると技術判断に見えるが、実際には組織とドメインに関する判断を含む。
- 技術的関心事は積極的に共通化してよい。ただし、その中にドメインが染み出している部分を見極める
- ドメインロジックは、名前と構造が似ているだけでは共通化の理由にならない。境界づけられたコンテキストが異なれば別物として扱う
- 判断軸は「コードの形が似ているか」ではなく、「変更理由とドメイン文脈が同じか」に置く
共通化は常に善ではない。安易な共通化は、アーキテクチャにとって静かに深い負債を生む。