[ソフトウェア開発]
EntityとDto
EntityとDtoの違い
TL;DR:
- エンティティはビジネスドメインの一部でありうる。それゆえ、それには振る舞いとドメイン内での異なるユースケースに適用される
- DTOはある処理や他の文脈への転送のためだけに使われる。例えば、それらには振る舞いがない;つまりとても基本的で大抵標準化されている保存と取得のための関数しか実装されていない
長い解説
- "Data Transfer Object(DTO)" がとても不明瞭に定義されているのに対して、"Entity" は様々な文脈で異なる解釈をされている
- "Entity"という用語にもっとも関連のある解釈は、私の意見としては以下の3つになる:
- エンタープライズJavaとJPAの文脈において:「データベースの中で保守される永続化データを表すオブジェクト」
- ドメイン駆動開発の文脈において(Eric Evansの発言):「属性よりもその独自性によって主要に定義されるオブジェクト」
- クリーンアーキテクチャの文脈において(Robert C. Martinの発言):「エンタープライズ横断的に重要なビジネスルールをカプセル化したオブジェクト」
JEEやJPAコミュニティはエンティティをもっぱらデータベースのテーブルにマッピングするものとして見ている。この見方はDTOの定義に非常に近い。そしてこれがこの混乱の元になっているのかもしれない。
ドメイン駆動開発の文脈においては(というのはRobert Martinの見方だが)、エンティティはビジネスドメインの一部でそれゆえに振る舞いを実装すべきなのだということだ。
Data Transfer Objectの本来の意味
- P of EAA: Data Transfer Object
- マーティンファウラーのサイトから
- もともとのDTOの利点は、リモートアクセスの呼び出しコストが高い状況において呼び出しを1つのDTOでまとめておくことで呼び出し回数を減らすことが目的だったようだ
- 一般的なJavaのアプリケーション開発では、DTOはテーブルとマッピングさせて使われることが多いように思う。そしてそれは呼び出しをまとめるという初期の目的は失われているように思う
- この使い方が昔は正しかったことがQiitaのコメントから伺える
VOの対になるのがEntityです。これは別名ReferenceObjectと言います。つまり、ValueとReferenceが対になっているのです。Entityは値にももちろん意味がありますが、それ以上に同一性が重要です。 つまり、全く値が同じでも(等価性があっても)識別性(通常Entityは永続化するので、主キー・識別子による区別と言い換えても良いです。少し乱暴ですが)において他のモノと区別されます。 これはEric Evans氏の「DDD」とか、Martin Fowler氏の「UML モデリングのエッセンス」に秀逸の説明があります。特に後者は比較的安価な本なのでご一読するのも良いと思います。
DTOは元々J2EEデザインパターン(古典です)で登場したパターンであり、レイヤー間を行き来する性質のオブジェクトという性質があります。 結果的に、VO+setterというのは形式的には間違いではないですが、VO、Entityとはちょっと切り口が違います。 昔の(暗黒時代)のEJBはリモートインタフェースが主で、当時としては深刻な性能問題があったので、DTOを組み立てて、それを少ない回数でまとめてレイヤー間(リモートインタフェース超え)で運ぶという役目が主でした。 従って、Data Transfer Objectということで運び屋なので、入れ子で内部的に、VOやミュータブルなオブジェクト(DTOなど)を保持する場合が多いです。 余談ですが、DTOをわざわざ作ると面倒なので、Data Transfer HashMapというパターンもありました。(決して個人的にはおすすめしませんが)