じぶん対策

日々学んだことをアウトプットして備忘録にしています。

DDD(Domain Driven Design: ドメイン駆動設計)について

参考文献

ドメイン駆動設計の用語と解説(抜粋版)
DDD難民に捧げるDomain-Driven Designのエッセンス
ドメイン駆動設計は何を解決しようとしているのか
クリーンアーキテクチャ完全に理解した   

ドメイン駆動設計とは

  • ひとことでドメイン駆動設計といっても下記のような文脈がある.

そもそもドメインって?

知識、影響、または活動の領域
ソフトウェアが表現する対象のこと。

開発思想としてのDDD

DDDの要点

  • ドメインモデルは、ドメイン知識を深めながら 反復的(iterative) に深化させていく
  • ドメインモデルが、開発者とドメイン知識をもつ人(ユーザ、専門家等)との間の共通言語となるようにする
  • ドメインモデルと実装コードとがきちんと対応付けられるようにする
  • 境界づけられたコンテキストの中のユビキタス言語で話す

境界づけられたコンテキストとは、マイクロサービスの境界をイメージするとわかりやすい。
システムが大規模になると関係者全てで統一してモデルを作るのは困難になる。
一定のコンテキストで分割し、それぞれの中で統一したモデルやユビキタス言語を用いる。
実装面でもモジュールを分割し、複数のコンテキストをまたがる場合はお互いの変更が影響を与えないように設計する。(後述の戦術的設計を参照)

背景

まず、業務をシステムに落とし込む際、以下の手順で行う。
1. 現実の業務を適切に抽象化した分析モデルの作成
2. 1で作成した分析モデルをもとにした設計

しかし、現実には分析モデルには存在しない概念が設計で必要になることが多く、この二つはどんどん乖離していく。(実装上の都合で処理を追加しても要件を満たせてしまうが、ドメインモデルからは遠ざかる)

乖離するとどうなるのか

  • 設計と分析モデルに乖離が大きいとそもそもソフトウェアが正確かどうかも疑わしい。
  • 設計と分析モデルの紐付けが複雑になればなるほどコードを理解するのが難しくなる
  • やがて設計が変更された際に分析モデルとの紐付けを維持できなくなる
  • それぞれの作業で得られる洞察が互いに生かされることはなくなる

特に最後のモデルの改善からソフトウェアに生かすことのできる利益を得るという部分がドメイン駆動設計の目的。以下参照
ドメイン駆動設計は何を解決しようとしているのか

戦術的設計

レイヤードアーキテクチャ

DDD本で言及されている、ドメインを隔離するためのアプリケーションアーキテクチャ。 分析モデル(ドメインモデル)が設計に忠実に反映されているかを確認するためには、ドメインを表現する責務をどこで持つかを明確にしないといけない。
レイヤードアーキテクチャは以下の四層に分かれる。 - UI/プレゼンテーション - アプリケーション - ドメイン - インフラストラクチャ

それぞれの説明は以下 - UI/プレゼンテーション層
ユーザーに情報を表示してユーザーのコマンドを解釈する責務を負う。 - アプリケーション層
ソフトウェア行うことになっている仕事を定義し、表現力豊かなドメインオブジェクトが問題を解決するように導く。やるべき作業を調整するだけで、実際の処理はドメインオブジェクトによって直下のレイヤで実行される共同作業に委譲する。 - ドメイン
ビジネスの概念と、ビジネスが置かれた状況に関する情報、およびビジネスルールを表す責務を負う。ビジネスの状況を反映する状態はここで制御され使用されるが、それを格納するという技術的な詳細は、インフラストラクチャに委譲される。この層がビジネスソフトウェアの核心である。 - インフラストラクチャ
上位のレイヤを支える一般的な技術的機能を提供する。これには、アプリケーションのためのメッセージ送信、ドメインのための永続化、ユーザインタフェースのためのウィジェット描画などがある。インフラストラクチャ層は、ここで示す4層間における相互作用のパターンも、アーキテクチャフレームワークを通じてサポートすることがある。

DDDパターン

そもそもドメインモデリングを提唱しているのはEric Evansの『Domain-Driven Design』という書籍。
この本はよくあるパターン本の一つ。先述したドメイン駆動設計を具体的な実装に落とし込むためのパターン。

基本

  • Ubiquitous Language(ユビキタス言語)パターン
    ドメインを正しく捉えた柔軟で価値の高いソフトウェアを設計するには、チームの共通言語を創造しなければならない。共通言語はユーザ、ドメインの専門家から、設計者、プログラマまで、分析/設計モデルからプログラムコードに至るまで、プロジェクトのすべての関係者、成果物に行き渡っていて、同じ意味で理解されるようなユビキタス(遍在的)な言語である。ドメインモデルがユビキタス言語となるようにし、ドメインモデルを介してプロジェクトが一体となるようにする。
  • Model-Driven Design(モデル駆動設計)パターン
    ユビキタス言語を実現するには、プログラムコードにおいてもドメインモデルが正確に表現されていなければならない。ドメインモデルとプログラムコードとが常にお互いを反映するように保つことで、ドメインモデルの変更がそのままコードの修正を促し、逆にコーディングの中で得られた新たなドメイン知識が即座にドメインモデルに反映されるようになる。このようにモデルとコードを緊密に結びつけるのがモデル駆動設計(MDD)である。MDDを実践するには、開発ツールやオブジェクト指向プログラミング(OOP)のようなプログラミングパラダイムが必要になる。
  • Hands-On Modeler(実践的モデラー)パターン
    もしモデラーがプログラムを書けなかったり、プログラマドメインモデルに興味を示さなかったら、MDDの利点であるモデリングとプログラミングの好循環は生まれない。また、チームのコミュニケーションもそこで停滞してしまう。MDDを通してユビキタス言語を実現するには、モデラーが動くプログラムを書けなければいけないし、同時にプログラマドメインモデルを理解し、修正できなければならない。つまり、チームのすべての開発者は、プログラムを書くモデラーでなければならない。

他にも16パターンが存在する。 まとめは以下のサイトにいい感じに載ってるから確認しておく。
DDD難民に捧げるDomain-Driven Designのエッセンス

まとめ

  • ドメイン駆動設計の目的は実際の業務(ドメイン)をモデル化したものと実装の差を少なくして、モデルの改善とソフトウェアへの反映を容易にすること。
  • そのためにモデルをできる限りソフトウェア上に表現することを目指す。
  • ひとことでドメイン駆動設計といっても下記のような文脈がある.