📖

[読書]Software Design (ソフトウェアデザイン) 2023年2月号 [特集]ドメイン駆動設計入門

2023/04/05に公開

感想

最近、ソフトウェア設計の本をいくつか読んでいる。数年前、オブジェクト指向やデザインパターンを学でから時間が経ってしまったため、復習も兼ねて学び直したいと思っていたところ、Sofware Design という雑誌で DDD に関する特集があったため、読んでみた。ドメイン駆動開発 DDD の本も読んでいたので、いい復習になった。

感想としては、とてもよくまとまっていて、DDD の全体像を理解するのによいと感じた。キーワードを拾って、そこから学びを広げていくための手引きとしても使えそう。普段は雑誌で勉強することはないが、最初のきっかけや一通り学んだあとの知識の整理には、雑誌で学ぶのも便利だなと感じた。

クラウドやマイクロサービス、AI などが台頭し、アプリケーション設計の重要性は高まっていくように思う。今後、設計がどのように変化していくのか、また、現在のベストプラクティスは何なのか、などについて興味があり、色々な本を読んでいる。構造化プログラミングやオブジェクト指向、関数型プログラミングなどのパラダイムの進化に伴い、言語やフレームワークは変化してきたが、DDD は OOP や FP の両方のパラダイムを取り入れていると認識している。ただ、その位置づけや考え方についてはまだ明確に理解できていない部分もあるので、今後の課題としたい。

読んだ内容を整理して以下にまとめます。

DDD の考え方

ドメイン駆動設計が前提とする考え方は、

事業活動の継続的な発展に貢献するため、事業活動とソフトウェアの設計を直接的に強く関連付けることを目標にする。

DDD の基礎概念

DDD(ドメイン駆動設計)を一言で表現すると、

ソフトウェアの開発において、関係者全員が同じ言葉(ユビキタス言語)を使いながら、明示的に境界づけられたコンテキストの中で、重要な業務知識をドメインモデルとして抽出し、それを設計の骨格として動くソフトウェアを作っていくアプローチのこと。

ユビキタス言語

同じ言葉を使って開発する

境界付けられたコンテキスト(Bounded Context)

ユビキタス言語の言葉が同じ意味で通用する範囲を規定する。その領域内(コンテキスト毎)で一貫性のあるドメインモデルを作る。業務の目的や関心事に応じてコンテキストを切り分ける

※ マイクロサービスなど分散アーキテクチャの設計の考え方と親和性が高いため、DDD が参照されることが多い

ドメインモデル

ある特定の事業領域や問題領域(=ドメイン※)について、その中心となる概念、データ、およびプロセスを表現するモデル。特定のビジネス領域におけるオブジェクトの集合体。

※ インターネットの「ドメイン」も同じこと

DDD におけるドメイン モデルの 3 つ の 用途 は、

・ 業務 知識 の 習得 と 整理
・ 開発 活動 で 意図 を 伝え 合う ため の 基本語彙
・ クラス 設計 や パッケージ 設計 の 骨格

⇒ それぞれ、深いモデルユビキタス言語モデル駆動設計(※)、に対応する。

(※) DDD では、ドメインモデルをそのままプログラムの基本構造とすることを強く主張されるので、ソースコードに業務知識が記述できているかという点をレビューの重要な観点にするのが良い。一方、議論するときのベースはソースコードではなくモデルベースで行うのが良い。

DDD の構成要素を 3 つに分類する

1. ドメインモデルに関する要素

エンティティ(Entity)

ドメイン内の重要な概念を表現し、ドメインのビジネスルールを実装する。一意の識別子(ID)で区別される「個別に認識できる実態」で、時間経過によって状態が変化する。

例:注文、商品、顧客、銀行口座など

値オブジェクト (Value Object)

エンティティのような識別性は持たず、属性によって識別され、その値のみに基づいて等価性が判断される。同じ値を持つ複数のオブジェクトが存在する場合がある。基本的に不変であり、イミュータブル。

例:日付、電話番号、金額、住所、座標など

集約 (Aggregate)

複数の関連するエンティティと値オブジェクトをまとめる概念。ドメイン内の関連オブジェクトをまとめることで、トランザクションでの一貫性確保や保管、キャッシュの最適化などを行う。DI(Dependency Injection)でのインターフェース(公開 API)を提供することで、アプリケーション層から集約にアクセスすることができる。

集約にはルートエンティティ(Aggregate Root)が存在し、集約内のすべてのエンティティをカプセル化して、外部からアクセスされる唯一のエントリーポイントとなる。

2. ドメインモデルを使う側に関する要素

アプリケーションはドメインモデルをコアにして、それを取り巻く周辺のレイヤと合わせて成立する。

アプリケーションサービス(ユースケース)

ドメインが公開している操作(集約)を組み合わせてユースケースを実現する。

「ファクトリー」パターンや「リポジトリ」パターンを使って必要な集約を手に入れ、その集約を使って計算判断を実行し、必要に応じてその計算判断の結果をリポジトリを使って記録(永続化)します

ファクトリ

複雑な集約を生成する責任を集約から分離するためのパターン

リポジトリ

集約の永続化と再構築の役割を集約やアプリケーションサービスから分離するためのパターン

※ドメインモデルとドメインモデルを使う側の関連のさせ方

本書では以下の三つを紹介

・ ドメインモデル+ 3 層構造
・ ドメインモデル+ポート&アダプター
・ クリーンアーキテクチャ

※他にも、ヘキサゴナルアーキテクチャ(やオニオンアーキテクチャ)などがある

⇒ ドメインモデル(複雑な業務ロジック)を隔離して、ほかの要素をドメインモデルに依存させる(逆は避ける)

⇒ オーブン・クローズドの原則(Open/closed principle)の考え方。ドメインはコアなので pluggable にする必要はないが、周辺レイヤは拡張できるようにする。依存オブジェクトは Construction Root で inject する。

3. 戦略的な設計に関連する要素

コンテキストマップ(Context Map)

複数の「境界づけられたコンテキスト」間の関係を俯瞰するための図。システム全体像を関係者で共通の認識にするために使う。

コアドメイン

事業活動の存続優位性を生み出す(事業のコアとなる)ドメインで、「業務が複雑」「自社独自の業務」の 2 つが合わさった領域。事業領域の全体にドメイン駆動設計のやり方を適用するのは現実的ではないので、「コアドメインに集中する」設計方針をとる。

進化する秩序(Evolutionary Order)

DDD において、ビジネスドメインの複雑さに対処するために使用される設計原則。進化する秩序に従って徐々にモデルを進化させることで深いモデルの構築につながる。

深いモデル

深いモデル は、最初の段階では見落としていた重要な業務ルールに気づいたり、業務ルールの背景にある暗黙的な枠組みが明示的に表現できるようになったりしたドメインモデル

GitHubで編集を提案

Discussion