概要
ドメイン駆動設計の有名な用語にエンティティというものがあります。
ほとんどドメイン駆動設計の代名詞のひとつと言っても過言でないほどの有名さを誇るこちらの用語ですが、なんとクリーンアーキテクチャにもまったく同じエンティティという用語が出てきます。
このエンティティという用語は名前こそ同じではありますが、実は完全に同じものを指しているわけではありません。
とはいえまったく違うものである、というわけでもありません。
要するにややこしい。
この記事はこのややこしい用語について、ドメイン駆動設計とクリーンアーキテクチャのそれぞれのエンティティが何を指していて、それがどのように異なっているのかについてを解説します。
それぞれのエンティティ
そもそもエンティティとは何でしょうか。
英和辞典を引くとエンティティとは「存在[実在]物」といった意味が出てきます。
これはかなり抽象的な意味です。
つまり、そもそもエンティティはかなり抽象的なもので文脈により意味合いが異なるものであるということです。
違いを比べるため、まず手始めにそれぞれのエンティティが何であるかを確認していきます。
ドメイン駆動設計のエンティティ
書籍エリックエヴァンスのドメイン駆動設計において、エンティティという用語は比較的早い段階で登場します。
とはいえそのタイミングはユビキタス言語やドメインエキスパートの話が一通り済んだ後、つまり読者は十分に疲弊している頃ですね。
そういったタイミングであるため、エンティティというものが理解しづらく感じることはあります。
しかし、実を言うと、このエンティティという代物自体は、それがどういったものかを理解するのは比較的難しくなかったりします。
一旦はユビキタス言語やドメインエキスパートなどの小難しい話があったことは忘れて、エンティティだけに焦点を当てて確認してみましょう。
エンティティとは
エンティティは端的に表現すると「同一性によって識別されるモデル」です。
同一性、識別、モデル。単語ひとつひとつの意味はわかるけど全体ではなんだかわかりづらい印象を受ける表現ですね。
まずは「同一性によって識別される」という点を確認していきます。
同一性によって識別
同姓同名という言葉があります。
この言葉は同一性を知るのに都合が良い言葉です。
私たちには氏名があります。名字と名前という組み合わせが日本では一般的ですね。
この名字と名前が一言一句同じとき、同姓同名であると言います。
さて、同姓同名という言葉の定義について再確認が終わったところで改めて本題に入ります。
たとえばあなたと同姓同名の人物が目の前にいたとしましょう。
このとき、あなたの目の前の人物はあなたと同じでしょうか。
もちろん違います。
あなたという人物と目の前の同姓同名の人物は同一ではありません。
同一という言葉が出てきました。
もう一つ、今度は逆の例を確認してみましょう。
私たちの氏名はときに変更される可能性があります。
その理由は結婚など様々ですが、往々にして起こりうることです。
たとえば、あなたの名字が変わったとします。
名字が変わる前のあなたと、名字が変わった後のあなたは別の人物でしょうか。
もちろん同一の人物です。
これらの例からわかる通り、私たちは自然と同一か同一でないかの判断をしています。
これが同一性です。
さて、この同一性はソフトウェアにおいても重要なものであったりします。
たとえば同じ名前のユーザーがいたとき、それらは同じユーザーでしょうか。
たとえばユーザーが名前を変えたとして、それらは別のユーザーでしょうか。
人はそれらの同一性を判断できますが、ソフトウェアはそれを判断するために何らかの指標が必要です。
そのとき利用されるのは ID つまり識別子ですね。
「同一性によって識別される」という言葉はプログラム上では「ID によって識別される」ということに置き換えることができます。
モデル
次はモデルについて考えてみましょう。
開発者にとってモデルというのはとても身近な用語です。
技術書などを眺めていると頻繁といっても差し支えないレベルでモデルという言葉が登場してきます。
ドメイン駆動設計においてもこれは同じで、第1部(しかもタイトル!)から登場します。
そんな身近に点在するモデルですが、改めて「モデルとは何か」と問われると案外困る質問だったりするのではないでしょうか。
ソフトウェア開発の文脈におけるモデルとは現実の事象または概念を抽象化して表すモノです。
抽象すなわち抽出して象るという言葉の通り、すべてを忠実に表現するのではなく、取捨選択をすることになります。
実際に取捨選択を行い、どの部分を抽出するのかについてはソフトウェアにより異なります。何が役に立つかは解決したい問題によって異なりますからね。
この事象あるいは概念を抽象化する作業がモデリングと呼ばれる作業です。
そして、その作業の結果として得られたものがモデルと呼ばれます。
同一性によって識別されるモデル
これら二つを組み合わせたものがドメイン駆動設計におけるエンティティです。
たとえば一般的なECサイトなどのユーザーはこれにあたります。
ユーザーは同姓同名のユーザーだったとしても同一ではありませんし、名前が変更されたとしても別のユーザーにはなれません。
つまりユーザーは同一性によって識別されます。
またユーザーはソフトウェアの利用者自身ではありません。ECサイトであれば必要な氏名や住所、電話番号などを抽出して表現されたオブジェクトです。
つまりユーザーはモデルです。
統括するとユーザーは同一性によって識別されるモデルです。
これはすなわちドメイン駆動設計におけるエンティティなのです。
クリーンアーキテクチャのエンティティ
クリーンアーキテクチャは特徴的な同心円の図が有名です。
この図を眺めてみるとエンティティ(Entities)という言葉が飛び込んできます。
冒頭にお話した通り、エンティティという言葉自体はドメイン駆動設計ですでに有名な用語になっています。
またドメイン駆動設計が語られるときに同時にクリーンアーキテクチャが語られることも多いです。
これらのためにドメイン駆動設計のエンティティと混同してしまう原因ともなっているように感じられます。
この章ではドメイン駆動設計の事は一旦忘れて、クリーンアーキテクチャにおけるエンティティがどのような代物として語られているのかに焦点を当てて探ってみましょう。
エンティティの解説文を読み解く
クリーンアーキテクチャの原文においてエンティティはひとつの解説項目として取り上げられ、仔細な解説がされています。
Entities encapsulate Enterprise wide business rules. An entity can be an object with methods, or it can be a set of data structures and functions. It doesn’t matter so long as the entities could be used by many different applications in the enterprise.
If you don’t have an enterprise, and are just writing a single application, then these entities are the business objects of the application. They encapsulate the most general and high-level rules. They are the least likely to change when something external changes. For example, you would not expect these objects to be affected by a change to page navigation, or security. No operational change to any particular application should affect the entity layer.
From: https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html
こちらの文章の言葉を拾いながら解説していきます。
まずは冒頭の内容です。
Entities encapsulate Enterprise wide business rules. An entity can be an object with methods, or it can be a set of data structures and functions.
こちらの文章は「エンティティはビジネスルールをカプセル化したメソッドのあるオブジェクトやデータ構造と関数の集合である」という内容です。
メソッドやオブジェクト、データ構造などのテクニカルな用語が現れていますね。
これはエンティティの具体的な実装に利用される手段について話しています。
エンティティの概念としての定義は次の文章に記述されています。
If you don’t have an enterprise, and are just writing a single application, then these entities are the business objects of the application. They encapsulate the most general and high-level rules.
要約すると「エンティティはアプリケーションにおいて、もっとも一般的で高次元なルールをカプセル化したビジネスオブジェクトである」といった内容です。
ルールとは何でしょうか。
たとえば水を例にしてみましょう。
気圧などの条件によって異なる事はありますが、一般的に水は0度で凍り始めます。また反対に100度を超えると今度は蒸発し始めます。
これは水というものの一般的な法則、つまりルールです。
もしもソフトウェアが解決しようとしている問題に対して、この水の法則が役に立つものであるなら、開発者はそのルールを抽象化して、水を表現するオブジェクトを開発します。
それは一般的に水のモデルでしょう。
つまりルールをカプセル化したオブジェクトというのは要するにモデルのことなのです。
エンティティの正体
ドメイン駆動設計におけるエンティティは「同一性によって識別されるモデル」でした。
クリーンアーキテクチャにおけるエンティティは「モデル」でした。
それぞれの定義を見比べると、条件が付いている分、ドメイン駆動設計の方が狭い範囲を示しているのがわかります。
もちろんドメイン駆動設計にもモデルは存在します。
ドメイン駆動設計のモデルは、具体的にはエンティティはもちろん、値オブジェクト、(ドメイン)サービスなどが含まれています(これら以外もありますが)。
これらのモデルはクリーンアーキテクチャが指しているものと同一ですね。
図に起こすと次のイメージになります。
クリーンアーキテクチャにおけるエンティティはドメイン駆動設計のモデルのことで、つまりエンティティ以外のモデリング要素も含んだすべてを指しているのです。
終わりに
何かを新しく学ぶ時、きっと多くの用語に出会うでしょう。
それらはまったく初めて見聞きする用語であることもあれば、以前どこかで見聞きした用語であることもあります。
とくに後者のどこかで見聞きした言葉には注意すべきです。
果たしてその文脈においてそれは以前見聞きした言葉について説いているのか、それともまったく新しい概念として紹介されているのか。
この認識を間違うと致命的な間違いに繋がることがあります。
そもそもまったく異なる言葉で表現されていればよいのですが、残念ながらどれだけ注意してもいずれは同じ言葉の用語が生まれてしまう事があります。
私たちにできるのは前後の文脈を注意深く確認し、それが自分が知っているあの用語なのか、それとも名前だけがたまたま同じなまったく新しい概念を示す用語なのか。
常に自問自答することが大切です。
用語も同一性によって識別する必要がある。
さながらエンティティのようですね。