[5]エンティティの振る舞い(メソッド)を検討
続いて、エンティティが持つ振る舞いについて検討していきます。ソフトウェア要件に登場する動詞に注目することで、メソッドの候補を洗い出していきます。
ここでは、テナントに対して「アクティブ状態を示す属性」を追加するのではなく、「アクティベートする」「ディアクティベートする」といったビジネス用語をそのまま振る舞いとして追加しています。これはDDDの設計パターンの1つである「意図の明確なインターフェイス」の考え方に従っています。
意図の明確なインターフェイスとは、クラス名やメソッド名に、その効果と目的に関する名前をつけて意図が正確に伝わるようにすることです。利用者がインターフェイスの中身を意識しないで済むように、実装方法や手段を名前に含めないようにします。また、振る舞いを実装する前にテストを書くことにより、利用者の視点で設計を行うようにします。
エンティティでは同一性を識別する本質に絞り込むことが重要であるため、それ以外は別のオブジェクトとしてモデリングしています。ここでは「ユーザー」から「個人」というエンティティを切り出し、「個人情報」という値オブジェクトを追加しています(なお、ユーザーのデータ構造を管理する方法について、ヴァーン・ヴァーノン氏は自分自身のブログにて「Fundamental Identityパターン」として整理しています)。
モデルの発展に合わせて、出てきた用語は随時、用語集に格納していきます。
[6]エンティティの作成方法を検討
それでは、これまで検討してきたモデルをコードとして実装します。
コンストラクタ
これまで説明してきたように、エンティティは一意である必要があります。そのため、エンティティのコンストラクタでは「識別子の生成に必要な情報」や「問い合わせを行うために必要な情報」を引数として渡します。これにより、エンティティ生成時からオブジェクトを一意に特定できるようになります。
ファクトリの検討
もし、エンティティの生成が複雑な場合はコンストラクタを直接呼び出すのではなく、ファクトリ(11章)を使用します。例えば、ユーザーエンティティの場合、テナントの「ユーザー登録する」メソッドがファクトリとなります。テナント経由でユーザーの作成を行うことで、オブジェクトの状態を正しく管理できます。
コンストラクタから「自己カプセル化」での呼び出し
コンストラクタの引数に渡された値が、不正でないことを保証するため、適切にバリデーションチェックを行う必要があります。この時、コンストラクタから直接フィールドにアクセスするのではなく、セッターを呼び出すことで、不正な値を防ぐことができます。
このような、クラス内部からのアクセスもアクセサメソッド経由で行うことを「自己カプセル化」とマーティン・ファウラー氏は呼んでいます(この後の「属性のバリデーション」にてコード例を紹介しています)。