ドメイン駆動設計と Red Hat
ユーザー企業での経験
私は証券会社の IT 部門ではない与信管理部で働く機会があり、ソフトウェア開発者とビジネスの専門家との間に如何に多くの知識の溝があるかを痛感した経験があります。
当時仕組債のエクスポージャーを管理できる仕組みを作りたいという要望が与信管理部のメンバーからあがりました。
仕組債は SPC(Special Purpose Company)を立てて担保債(リスクの低い JGB、つまり日本国債)を購入し、突っ込みます。投資家にはこの SPC が発行する仕組み債を売るわけですが、JGB のようにリスクの低い債券は利率も低いため、このままでは誰も買ってくれません。そこで証券会社が SPC とデリバティブ取引をし、投資家へ還元する利率を高めます。ここで使用されるデリバティブ取引はたとえば固定金利と変動金利を交換する金利スワップ、クーポンの支払いを円からドル(もしくは担保債がドル建てであればドルから円)に変える為替スワップ、為替スワップをクーポンの支払いごとに選択できるようなスワップションです。担保債に入れているのが転換社債の場合(社債を株式に変換可能な債券)は、エクイティスワップなども組み入れます。
私が所属していた証券会社はユーザー部門で出てきた要望を自分たちの部門で開発する End User Computing が盛んで、本システムも自分たちでつくることになりました。このプロジェクトが証券会社入社後、ソフトウェアの専門家として参加した初めてのプロジェクトで、ビジネスの専門家が発する言葉を調べるとまた未知の言葉が出てくるという状況でした。
ビジネスの専門家とのコミュニケーション
上記の仕組債のリスク見える化システムを構築するとき、すぐ近くにビジネスの専門家が存在していたにもかかわらず、十分なコミュニケーションができたとは思えません。IT 業界出身者が金融のユーザー部門に入社し、金融用語が全くわからない点を考慮してくれ、色々教えてくれましたが、それでも十分ではなかったと思います。最終的には最近の Web にあるようなレスポンシブな Web 画面を構築することができ、ビジネスの専門家に喜んでもらうことができました。
これが一般的なソフトウェア開発現場だとしたらどうでしょうか。多くの企業においてソフトウェア開発者とビジネスの専門家の間には IT 部門、自社の IT 専門子会社、SIer、2次請、3次請が介在します。しかも契約の壁もあり作りたいものがちゃんと伝わっていないということが多くなっているのではないでしょうか。
このプロジェクトは IT 部門によって一度実装を試みられたことがありますが、仕組債の複雑さ、登場人物の多さからエクスポージャーをどう捉えればいいのかという点を、ビジネスの専門家とうまく会話をできず長い間放置されていたプロジェクトでした。
DX を推進するには
このシステムが SoR(System of Record)のような長い時間をかけて構築しても問題ないシステムであればこれまでと同じやり方で問題ないと思います。ただし、SoR の領域は将来コモディティ化し SaaS 企業によって UI/UX の差や価格によって決まっていく世界になると私は考えています。ビジネスの価値を産むわけではないシステムに多額の構築コストや運用保守費をかけて自社でお守りをする時代はそのうち終わりを迎えます。
問題は SoE(System of Engagement)でこちらは他社とのビジネスの差をつけるための仕組みとなります。他社とのビジネスの差異をつける根幹であるためじっくりと時間をかけて構築していくと、他社に遅れをとることになります。
そして重要なのが、ビジネスの専門家とソフトウェアの専門家のコラボレーションです。ソフトウェアの専門家だけだと話になりません。その領域において、違法性の高いことをやろうとしていたらソフトウェアの専門家だけでは判断できませんし、逆にビジネスの専門家だけでも従来の仕組みしか思い付かないでしょう。
今こそドメイン駆動設計
ドメイン駆動設計が提唱されてもうかなりの時間が経っていますが、それでも今からでも取り組むべき要素が網羅されています。上記に記載した通り、一番重要なのはビジネスの専門家(ドメイン駆動設計においてはドメインエキスパートという)とソフトウェアの専門家のコラボレーションという点です。そしてビジネスの専門家とソフトウェアの専門家間では「ユビキタス言語」と呼ばれる両者がお互いに理解できる言語を定めて、それに則って会話をします。お互いのコミュニケーションの齟齬をなくすためです。
また、同じ「商品」という言葉でも、購買部の人が言う「商品」と配送部の人が言う「商品」では文脈によって意味が異なります。文脈が変わる境目を定義することもドメイン駆動設計では戦略的要素として挙げられており、「境界づけられたコンテキスト」といいます。マイクロサービスをどう区切って考えればよいのかという質問をよく受けますが、この「境界づけられたコンテキスト」がマイクロサービス化を考える上での一つの目安となるでしょう。
ドメイン駆動設計で重要なのはビジネスの活動領域であるドメインをモデル化する際に、利用するアプリケーションやインフラに依存するような設計にしてはならないということです。そして一度値が決まると以降値が変更されない「Value Object」、「Value Object」を組み合わせた「エンティティ」でビジネスの活動領域のモデル化をおこないます。「Value Object」は Immutable にすることを心がけ、一度生成されたらオブジェクトが死ぬまでその値を保持し続けます。
モデル化がしっかりと行えていれば、後から誰が見てもわかりやすい、分岐の少ない、変更に強いコードが生成されます。
以下は映画チケットの料金を計算するシステムの一例となります。
DDD を考慮せずに記載されたコード
DDD を考慮して記載されたコード
また、実装したいビジネスの活動領域をモデル化さえできれば、アプリケーションやインフラは後から変更が可能になります。これはドメイン駆動設計における「レイヤードアーキテクチャ」の概念です。みなさんの現場では、利用する技術が先にありきになっていないでしょうか。
「レイヤードアーキテクチャ」の一つに「オニオンアーキテクチャ」というものがあります。
ビジネスの活動領域をモデル化した中心にある「ドメインモデル」は非常に重要なモデルであり、これが事業の核であると言えるでしょう。上記の例で出てくる Coupon や MovieTicket がそれに当たります。
このドメインモデルはどの層にも依存しません。
逆に外側の層は内側の層に依存しています。ドメインサービスはドメインモデルに依存していますし、アプリケーションサービスはドメインサービスに依存しています。
アプリケーションサービスは「境界付けられたコンテキスト」間のデータの変換を担ったり、トランザクションを担ったりします。また、外部へ公開する Endpoint を定義したり、データベースに書き込んだりという処理が含まれます。
Red Hat とドメイン駆動設計
上記のインフラストラクチャの層には Red Hat AMQ、Red Hat Data Grid、Red Hat Ceph Storage など、用途に応じて様々なプロダクトを選択することが可能です。
また、Red Hat AMQ、Red Hat Data Grid、Red Hat Ceph Storage に接続してデータを収集したり、データを格納するための Adapter、つまりアプリケーションサービスの層で Red Hat Fuse を選択することができます。Red Hat Fuse は様々なアプリケーション・外部システムへの接続プラグインを持っていることから非常に簡単にインフラを切り替えられるようになるでしょう。
Red Hat Fuse について詳しくは以下を参照してください。以下は Apache Camel の記事ですが、Apache Camel は Red Hat Fuse の上流プロジェクトです。
https://jcug-oss.github.io/article/why-do-we-have-to-learn-camel-q
また、API Component を利用する上では下記記事が参考になります。https://rheb.hatenablog.com/entry/201903-camel-api-component-framework-intro
上記に加えてドメインサービスには Red Hat Decision Manager を用いることができます。
最後に
私が証券会社に戻ってもう一度同じシステムを担当するのであれば、確実にドメイン駆動設計を採用します。ドメインモデルをしっかりと定義して変更に強いモデルを作成するでしょう。あとでコードを見る人が理解しやすいコードになり、テストコードもすっきりとします。
ドメイン駆動設計をこれから始めようと思う方は、Eric Evans が書いた書籍を読んでそのあまりに抽象的な記述に挫折するかもしれません。もしドメイン駆動設計でシステムを変えようと思っている方はぜひ Red Hat の営業にお知らせください。何かお手伝いできることがあるかと思います。