エバンス分類
2005年12月14日
彼の優れた著書「Domain Driven Design」において、エリック・エバンスは、遭遇する可能性のあるさまざまな種類のドメインオブジェクトの分類を作成しています。
- エンティティ:時間と異なる表現を通して一意のアイデンティティを持つオブジェクト。これらは「参照オブジェクト」と呼ばれることもあります。
- 値オブジェクト:属性の組み合わせとしてのみ意味を持つオブジェクト。すべての属性の値が同じである2つの値オブジェクトは、等しいとみなされます。値オブジェクトについては、P of EAAでも説明しています。
- サービス:ドメインのコンテキスト内でのスタンドアロン操作。サービスオブジェクトは、1つ以上のサービスをオブジェクトに集約します。通常、実行コンテキスト内では、各サービスオブジェクトタイプにつき1つのインスタンスしかありません。
この分類は、ドメインモデルに必要なものに関する私の経験とよく合致するものです。問題は、この3つの概念を正確に定義することが難しいことであり、「見ればわかる」というカテゴリーに属します。
そのため、いくつかの例が役立つかもしれません。エンティティは通常、顧客、船舶、賃貸契約など、大きなものです。値は通常、日付、金額、データベースクエリなど、小さなものです。サービスは通常、データベース接続、メッセージングゲートウェイ、リポジトリ、製品ファクトリなど、外部リソースへのアクセスです。
エンティティと値の明確な違いの1つは、値は等価メソッド(およびハッシュ)をオーバーライドするのに対し、エンティティは通常オーバーライドしないことです。これは、通常、処理コンテキスト内で同じ概念エンティティを表すオブジェクトを複数持つことを望まないためですが、「5.0」オブジェクトを複数持つことについては気にしません。値はプリミティブ(言語が区別する場合は)または特別な言語サポートを持つ(.NETのように)ことができますが、必ずしもそうである必要はありません。重要なルールは、値オブジェクトは不変であるべきです(そうでなければ、エイリアシングのバグに巻き込まれます)。値(私の身長など)を変更するには、高さオブジェクトを変更するのではなく、新しいオブジェクトに置き換えます。
サービスオブジェクトは、多くの場合、グローバル変数、クラスフィールド(Robert Martinの用語ではモノステート)、またはシングルトンを使用して実装されます。確かに、通常は単一である、つまり1つしか存在しませんが、その方法にはさまざまなものがあります。通常、特異性は処理コンテキスト内にあるため、マルチスレッド環境ではスレッドごとに1つです。いずれにしても、実装メカニズムを他のドメインオブジェクトから隠して、簡単に変更できるようにする必要があります。エリックは著書の中で、サービスはステートレスであるべきだと述べていますが、それについて話し合った結果、彼はもはやそれは必要ないと考えています。ただし、それができれば理想的です。
この分野の問題の1つは、この用語は、喚起力があるものの、他のアイデアとひどく混同されることです。エンティティは、データベーステーブルまたはデータベーステーブルに対応するオブジェクトを表すために頻繁に使用されます。サービスには、サービス指向アーキテクチャ全体に加え、アプリケーションアーキテクチャのサービスレイヤーがあります。そのため、これらの用語を使用する場合は、ドメインモデルのコンテキスト内で、エリックの著書における意味に従って使用していることを明確にする必要があります。そのため、人々がこのようにこれらの単語を使用していると仮定する際は注意してください。それらは非常に多義的です。残念ながら、他に良い選択肢はありません。