DDD ドメイン駆動設計入門 〜 基礎的な用語を理解する
エリック・エヴァンスのドメイン駆動設計
https://www.amazon.co.jp/dp/4798121967
この書籍を理解するにあたって、基礎となる用語を理解するために纏めました。
ドメイン エキスパート
扱っているテーマについて誰よりも良く知っている人。
例えば、ゲーム開発等だと仕様について把握している人。
何かの機能を作るとした場合、その機能を考えたディレクター・プランナーがドメインエキスパート。
ユビキタス言語
ユビキタス言語とは、ドメインエキスパートやソフトウェア開発者を含めたチーム全体で作り上げる共通言語のこと。
- 実践ドメイン駆動設計p.20
ユビキタス言語やソースコードは日々変化し続けます。そのため、ユビキタス言語を用語集化しようとドキュメントを作るのは現実的ではありません。ある用語に説明が必要だと思ったときは、用語集を作るのではなくそれを表すソースコード上のモデルにコメントを書くほうが現実的です。
- わかる! ドメイン駆動設計 p13
名前のない概念やあいまいな概念をはっきりさせ、名前をつけてユビキタス言語として確立する。
ドメイン
一言で言うのは難しい。引用すると、
ドメインは「領域」の意味をもった言葉です。ソフトウェア開発におけるドメインは、「プログラムを適用する対象となる領域」を指します。重要なのはドメインが何かではなく、ドメインに含まれるものが何かです。
たとえば会計システムを例にしてみましょう。会計の世界には金銭や帳票といった概念が登場します。これらは会計システムのドメインに含まれます。物流システムであればどうでしょうか。会計システムとは打って変わって貨物や倉庫、輸送手段などの概念が存在し、それらがそのまま物流システムのドメインに含まれます。このようにドメインに含まれるものはシステムが対象とするものや領域によって大きく変化します。
成瀬 允宣. ドメイン駆動設計入門 ボトムアップでわかる!ドメイン駆動設計の基本 (Japanese Edition) (Kindle の位置No.465). Kindle 版.
すべてのソフトウェアプログラムは、それを使用するユーザーの何らかの活動や関心と関係がある。
ユーザーがプログラムを適用するこの対象領域が、ソフトウェアのドメインである。
組織が行う事業やそれを取り巻く世界のことだ。
事業が市場を定義して、プロダクトやサービスを販売する。組織にはそれぞれ、自分たちの対象とする領域についてのノウハウや物事の進めかたがある。
その領域、そして業務を進めていくための方法が、ドメインだ。
- 実践ドメイン駆動設計p.41
開発するアプリケーションの対象となる領域。
例えば、銀行業務システムを作るとしたら、銀行業務のドメインを理解する必要がある。
会計ソフトなら、会計業務。
コアドメイン・サブドメイン
たとえば会計ソフトを開発しているとしましょう。このソフトウェアのドメインは会計業務ですが、内部の機能をみていくと、簿記をつける機能や印刷機能、データをグラフで表示する機能などがあります。
ソフトウェアの価値をもたらす部分、ビジネスの問題を解決する部分がコアドメインですから、上記の会計ソフトなら簿記をつける機能がコアドメインとなるでしょう。
コアドメイン - ビジネスの問題を解決する部分
サブドメイン - 本質と無関係な部分
ドメインモデル
ドメインを表現したモデル。OOPなら、プログラム中のオブジェクトモデルとして表現される。
事象、あるいは概念を抽象化する作業がモデリングと呼ばれる。
ドメインモデルをコードに落とし込む段階で、考慮漏れやより良いモデル、ユビキタス言語を見つけることがあります。この場合、必ずドメインモデルやユビキタス言語にフィードバックし、常にコードが正確にドメインモデルを表現するようにします。
ドメイン駆動設計では、設計がコードであり、コードが設計なのです。
-わかる! ドメイン駆動設計 p.18
ドメインロジック
上記ドメインを表現するロジック。ビジネスロジックとも言い換えられる。
そのアプリケーション固有の処理やルールが記述される。
UIやサーバー通信、ライブラリ部分はドメインロジックでは無い。
https://wa3.i-3-i.info/word13666.html
レイヤーの概念
ユーザーインターフェイス (プレゼンテーションレイヤー)
ユーザに対して情報を表示し、ユーザの命令を解釈する。
アプリケーションレイヤー
アプリケーションの活動を調整する薄いレイヤ。ビジネスロジックを含まない。また、ビジネスオブジェクトの状態を保持しない。しかし、アプリケーションの処理の進み具合を保持することがある。
ドメインレイヤー
ドメインについての情報を含むレイヤ。業務ソフトウエアの心臓部。ビジネスオブジェクトの状態を保持する。ビジネスオブジェクトの永続化処理をインフラストラクチャ層に委託する。まれにビジネスオブジェクトの状態もインフラストラクチャ層に委託することがある。
インフラストラクチャレイヤー
他のすべてのレイヤを補助するライブラリとして働く。レイヤ間の情報のやり取りを制御し、ビジネスオブジェクトの永続化を実装する。また、ユーザインターフェイス等を補助するライブラリを含む。
エンティティ
一意性を持つものとして分類できるオブジェクトがあります。ソフトウエアの様々な状態の中で、常に同一であり続けるオブジェクトです。
(中略)
オブジェクトの存在期間はシステムの寿命に及びます。
このようなオブジェクトをエンティティと呼びます。
- domain-driven-design-quickly.pdf p26
アプリの実行中に存在する一意なオブジェクト。
一意なIDなどが付く。
バリューオブジェクト
エンティティに対して、一意ではないオブジェクト。
バリューオブジェクトは変更できないようにするべき。コンストラクタで作成された後、破棄されるまで変更できないようにする。
一時的なデータ受け渡し用オブジェクトなど。
ここに厳守すべきルールが出来上がります。つまりバリューオブジェクトが共有可能ならば、変更不可能にすること。バリューオブジェクトは小さくてシンプルなオブジェクトにすること。他のオブジェクトがバリューオブジェクトを必要とするときは、単純に値だけを渡してやるか、バリューオブジェクトそのものをコピーして渡してやること。
- domain-driven-design-quickly.pdf p29
サービス
ドメインにはどのオブジェクトにも属さないような振る舞いが幾つもある。
そのような場合、無理にエンティティやバリューオブジェクトに機能を実装せず、サービスに実装する。
ドメインにこのような振る舞いが見つかった場合、最もよい方法はこの振る舞いをサービスとして定義することです。サービスは内部に状態を保持せず、単純に機能だけを提供します。
サービスが提供する機能は重要です。サービスは特定のエンティティやバリューオブジェクトのための機能をまとめます。サービスはわかりやすく定義したほうがいいでしょう。そうすればドメイン内部の区分が明確になり、概念もカプセル化されます。サービスとして提供される機能を、エンティティやバリューオブジェクトに含めてしまえば混乱が起きるでしょう。このような機能はどのオブジェクトに含めればいいのか明らかでないからです。
- domain-driven-design-quickly.pdf p31
サービスの3つの特徴
- サービスとして作成される操作はドメインの概念をあらわしているが、エンティティやバリューオブジェクトに含めると違和感がある。
- サービスとして作成される操作はドメイン内の他のオブジェクトから参照される。
- サービスとして作成される操作は状態をもたない。
モジュール
ドメインモデルはどんどん大きくなっていく。
ドメインモデルを複数のモジュールの集まりとして再構築する。
モジュール化は関係する概念やタスクを組織して複雑性を低減する方法。
参考書籍
https://booth.pm/ja/items/392260
https://www.infoq.com/jp/minibooks/domain-driven-design-quickly/