境界づけられたコンテキスト間の連携方法を示す「統合パターン」
次に、データとプログラムの連携方法を示す5つの「統合パターン」について紹介します。
(1)共有カーネル
「共有カーネル」は複数ドメインにおいて共有が必要な部分に、共通で使用するドメインモデルを構築してソースコードレベルで共有するパターンです。共有カーネルに変更が必要な場合は他のチームの承認が必要となるため、この部分は極力小さくします。
(2)巨大な泥団子
DDDでは境界づけられたコンテキストを適切な大きさに分割して管理します。しかし既存システムが大規模で複雑な場合、そのまま大きな固まりとして捉えることを「巨大な泥団子」と呼びます。連携システムを巨大な泥団子とみなす場合、自分たちの「境界づけられたコンテキスト」に「巨大な泥団子」のモデルが侵食してこないよう注意します。
(3)公開ホストサービス(OHS:Open Host Service)
「境界づけられたコンテキスト」の内容にアクセスできる公開サービスを「公開ホストサービス」と呼びます。最近ではREST形式のWebサービスが主流となっています。
公開されたサービスを利用するクライアントは複数存在していても問題ありません。新しい機能を提供する場合は、公開サービスを拡張します。ただし、特定のクライアントしか使用しない場合は、特定クライアント向けのサービスを公開します。
(4)公表された言語(PL:Published Language)
2つの境界づけられたコンテキスト内のモデルを変換する場合、共通の言語が必要となります。これを「公表された言語」と呼びます。最近ではJSONとXMLがよく使用されています。ドキュメントにより定義された共有言語であり「公開ホストサービス」と組み合わして使用されることが一般的です。
(5)腐敗防止層(ACL:Anti Corruption Layer)
連携する2チームの関係が良好な場合は適切な変換層が用意されることになりますが、連携先のチームの協力を仰げない場合は「腐敗防止層」を作成します。
下流側のチームは、上流側の機能を自コンテキストのドメインモデルとして変換するために「腐敗防止層」というレイヤを作ります。データを「受信」する場合と「送信」する場合の両方のケースが存在します。このレイヤでは、2つのコンテキスト間のモデル変換を双方向に行います。
以上、コンテキストマップを書き、境界づけられたコンテキスト間の関係を明確にする方法を紹介しました。これらの作業は、描画ツールを使用しても問題ありません。ただし、議論するべき内容がツールの使い方やモデル記法の話にならないように注意します。同様に、クラス名やマッピング内容等をコンテキストマップに記載しても構いませんが、コミュニケーション用の地図であることを意識し、最新化が面倒なドキュメントにならないように注意します。
SaaSOvationにおけるコンテキストマップの例
第2回となる前回は、SaaSOvationというサンプルプロジェクトをドメイン分割する方法について紹介しました。今回はコンテキストマップを用いて境界づけられたコンテキストを整理する例を見てみましょう。
SaaSOvationにおける「境界づけられたコンテキスト」の分析
まず「境界づけられたコンテキスト」が適切に分割されているかを検討します。IDDDではコンテキストマップの書き方を独自に拡張したBrandolini氏の記述方法を用いて検討します。
この例では「コラボレーションドメイン」の中に「コラボレーション」以外の「ユーザーと権限」という別の概念が混ざっていることを示しています(本来は3つの境界づけられたコンテキストに分割されますが、まだ2つにしか分割されていない場合の例となります)
この2つのコンテキストの関連を表す接続部分を「統合ポイント」と呼びます。1つのコンテキストに複数ドメインの概念が混在している場合、Brandolini氏の記法では、警告の印として「三角の警告マーク」を用います。この図を用いることで、コンテキストの「統合ポイント」において、どのような目的で概念が混在しているのかを理解することができます。
SaaSOvationにおける「コンテキストマップ」の洗練
別ドメインの用語が1つのコンテキストに含まれていることが判明した場合、その用語をコンテキストマップに書き出していけば、正しい場所がどこであるかを把握できるようになります。正しいコンテキストマップを1回で書こうと思わずに、何回も議論することによって洗練させていきます。
コアドメインで本質的ではない部分をサブドメインに移していく「隔離されたコア(今後の連載によって紹介予定)」パターンによって、「コラボレーションコンテキスト」から「認証・アクセスコンテンテキスト」を分離したコンテキストマップが以下となります。
このコンテキストマップでは、コンテキストの分離に加えて、コンテキストの統合ポイントに「OHS(公開ホストサービス)」「PL(公表された言語)」「ACL(腐敗防止層)」といった「統合パターン」も記載しています。
SaaSOvationにおけるコンテキストの統合方式例
続けて、複数の境界づけれらたコンテキストを連携する実装イメージについて見ていきましょう。
他コンテキストに依存しない設計
SaaSOvationの「アジャイルプロジェクト管理コンテキスト」は、上流の「認証・アクセスコンテンテキスト」に強く依存しないように、非同期処理を用いて実装しています。従来の開発では外部サービスを同期処理で呼び出すことが一般的ですが、DDDでは非同期処理がよく使用されます。
これはDDDの場合、システムを1つの大きな固まりではなく、複数の境界づけられたコンテキストにて実装することが多いためです。リアルタイムなリモート呼び出しの場合、ネットワーク接続エラーが発生したりパフォーマンスが悪くなったりする問題があります。そこで、他のコンテキストにアクセスできない場合でも、自分のコンテキストが正しく動作するように設計します。
リアルタイム性よりも「結果整合性」を重視
これまでのシステム開発ではリアルタイム性が重要だと考えられていました。しかし、実際にドメインエキスパートと会話してみると、業務的に問題がなければ、リアルタイム性はそれほど重要ではないことがわかります(もちろん、銀行口座など、クリティカルな整合性が必要な分野では、分散トランザクションなどを用いてリアルタイムに同期を図っていく必要があります)。このようにリアルタイム同期が行われなくても、状態の整合性が最終的に取れていれば問題無いことを「結果整合性」と呼びます。