DDD実践入門を読んでエンティティや値オブジェクト、モデリングについて整理してみました。
目次
DDDとは
「顧客と開発者が業務を戦略的に理解し、共通の言葉を使いながらシステムを発展させる手法」です。
具体的には、チームの共通言語である「ユビキタス言語」を用いて「ドメインモデル」を構築し、それをコードとして実装します。また大規模で密結合なシステムにならないように、「ドメイン」と「境界づけられたコンテキスト」でシステムを分割し、「コアドメイン」という最重要領域に集中して開発を行います。
DDDは高品質のソフトウェアを設計する手法
ここでいう高品質とはバグがないということではなく、ビジネス的に成功していることを指しています。
「事業を理解し、チームの知識を1つにまとめる」ことを重視し、それを「ユビキタス言語」と呼ばれるチームの共通語でプログラムを実装します。
DDDの3原則
- コアドメインに集中すること
- ドメインの実践者とソフトウェアの実践者による創造的な共同作業を通じて、モデルを探究すること
- 明示的な境界づけられたコンテキストの内部で、ユビキタス言語を語ること
DDDで重要なことはビジネス的に成功しているソフトウェアを構築すること
DDDの用語など
モデル
抽象化によって不要な詳細を省いたもの
ドメインモデル
複雑な業務ドメインの中から、システムに必要な概念を適切に抽出したもの
ドメイン
チームが取り組んでいる事業全体
コアドメイン
事業的に最も重要で戦略的に不可欠な部分
サブドメイン
コアドメインではな補助的な部分
境界づけられコンテキスト
ドメインの課題を解決する部分
エンティティと値オブジェクト
エンティティ
- 一意なものを表現する概念
- 一意であるため長期にわたって変化できるオブジェクト
- 一意に識別して変更を管理する必要がないものは値オブジェクト
値オブジェクト
- 一意に識別する必要がないオブジェクト
- 従来はシンプルな文字列型や数値型で実装してしまうような情報を「値オブジェクト」として実装することで、業務をコードとして明確に表現できるようになる
→ primitive型と対比すると値自体に振る舞いを持たせることで凝集度を上げることができる
モデリングとエンティティ(エンティティ発見の流れ)
① ソフトウェア要件の理解
設計を始めるにあたり、まず業務内容から整理していきます。開発する対象業務についてドメインエキスパートから要望を聞き出していきます。
ここでは業務仕様を簡単なソフトウェア用件という形でユースケースやユーザーストーリという形で作成します。
② モデリングを検討しエンティティを抽出
チームで共通のユビキタス言語を構築することを意識して、ドメインエキスパートと議論を行います。
エンティティの抽出においては、シナリオにおいて「変更」というキーワードがある箇所に注目します。主語の用語がエンティティとなる可能性が高くなります。
③ エンティティを識別する属性と振る舞いを検討
エンティティに注目してモデリングを行います。エンティティ設計の初期段階ではエンティティを一意に特定する属性と振る舞いにだけ注目します。
④ 「一意な識別子」の設計
エンティティを識別する一意な識別子を検討します。
一意な識別子を決定したら、一意な識別子(IDや主キー値)の生成方法と生成タイミングについて検討します(生成方法と生成タイミングは省略)。
一意な識別子を設定した後は、その識別子の値を変更しないようにします。もし、識別子が設定済みにもかかわらず、変更処理が呼び出された場合はエラーとなるようにしなければいけません。
⑤ エンティティの振る舞い(メソッド)を検討
エンティティが持つ振る舞いについて検討していきます。ソフトウェア要件に登場する同志に注目することで、メソッドの候補を洗い出していきます。
⑥ エンティティの作成方法を検討
これまで検討してきたモデルをコードとして実装していきます。
エンティティは一意である必要があるため、エンティティのコンストラクタには「識別子の生成に必要な情報」や「問い合わせを行うために必要な情報」を引数として渡します。
⑦ エンティティのバリデーションを検討
エンティティでは「属性単位」「オブジェクト全体」「複数オブジェクト時」という3つの粒度に分けてバリデーションを管理します。
属性単位
エンティティの属性/プロパティに値をセットする場合、「空ではないか」「5文字以上か」「30文字以下か」といった妥当性のチェックを行います。
オブジェクト全体
オブジェクト全体のチェックでは、実装クラスに対応した「バリデータ」クラスを作成し、適切なタイミングで呼び出すようにします。
複数オブジェクト時
複数オブジェクトの状態が妥当かチェックするケースでは、必要な数だけバリデータを用意します。