Value と Entity

きっかけは忘れたのですが、一昨日会社で Value Object の定義の話になって、Twitter でつぶやいたところ議論が盛り上がったのでログを残しておきます。
5/1追記: 個人的に重要だと思うところを太字にしました。あと、コメントを追記しました。

glad2121 少し頭痛が... 単なる寝不足か? Value Object で議論しすぎたか?
glad2121 概念的な Value を「不変、かつオープンなもの」と仮に定義してみよう。1が2に変わったら、それは別インスタンス。製品の仕様みたいに、仮に不変であっても非公開な情報があればエンティティ。
glad2121 Entity は価値を保有する。Value は価値を定義する。
glad2121 Valueアイデンティティがないってほんと? Value 自身がアイデンティティじゃないのか?

tadayosi @glad2121 それはアイデンティティをどう捉えるか次第では? GLADさんのように捉えるなら、Valueの定義は「それ自身がアイデンティティとなるもの」とすればいいだけ。
tadayosi @glad2121 でも普通のアイデンティティの使い方では、「黄色にアイデンティティがある」とか「2にアイデンティティがある」とか言うのは不自然。
glad2121 @tadayosi それはなぜだろう? 2と2が同じなのは当たり前だから? 主張するまでもない? 同一性が曖昧なものに同一性を定義するのがアイデンティティ? いぇ、個人的にはアイデンティティの定義がしたいわけじゃなくて、Value の定義をしたいのですが。(^^;)

やはり、Value にもアイデンティティ(同一性)はあると思います。それが関係者の間では自明なので強調しないだけ。モデリングでは、クラスではなく属性で表したり、重要でなければ省略することが多い。概念レベルで Value の議論をするのは、あまり建設的でないかもしれませんね。

yyamano @glad2121 概念だから?
yyamano @glad2121 オープンであること、価値を保有/定義というのはよく理解できませんでした。もう少し詳しく説明してもらえませんか。
tadayosi @glad2121 哲学議論としてならその疑問はいいのですが、単なる感覚的な用法としてですので。その感覚が共有できない、ということであればそれ以上議論の余地はないです。
tadayosi @glad2121 Valueの定義についてなら、Fowlerの定義はこうですね: http://martinfowler.com/eaa...
tadayosi @glad2121 "A small simple object, like money or a date range, whose equality isn't based on identity."
glad2121 @yyamano オープンというのは、Value を使いたい場合、リポジトリから検索する必要はなく、自分で作成できるという意味です。言語内であれば、new できたり、異なる言語でも必要な範囲で型定義することができます。
glad2121 @tadayosi それは僕も見ました。でも、その定義は実装(解決領域)での話では? Java なら == じゃなくて equals で比較する必要があるよってことですよね。昨日、Fowler の Value と言ったのとは矛盾した発言ですが... (^^;)
glad2121 発端は、単なる(と言うと少し語弊があるかも)データの寄せ集めを Value って呼ぶのやめようよ、というだけの話。DDD はもう一度読み直してみます。

J2EE パターンの Value Object を Data Transfer Object と言い換えたように。
JPA の @Embedded、PofEAA だと Embedded Value に相当するのだと思いますが、参照オブジェクトの埋め込みも可能なので、Fowler のこの命名はイマイチですね。

tadayosi @glad2121 "equality" というのは別に実装の話ではないですよ。概念的にも、同値性っていうのは考える必要がありますよね? その概念の同値性が、アイデンティティでは求められないよ、と言っているだけであって、Javaのequals云々というのは関係ないのでは?
glad2121 @tadayosi 同値性が問題になるのはインスタンスを複数作っちゃうからでは? 概念的には、2 というインスタンスは1つしかないと思うんだけど。@tadayosi さんは Value の同値性とはどう定義されますか?
everpeace @glad2121 インスタンスno
everpeace @glad2121 インスタンスの定義が曖昧なような・・・
everpeace @glad2121 集合(クラス)の要素という意味でのインスタンスでしょうか??であれば2は「整数」のインスタンスであって、「2」というクラスのインスタンスではないような・・・
everpeace @glad2121 解決領域(実装?)ではレイフィケーションしてObjectクラスのインスタンスとして「表現」するしかないから、1つのインスタンスにならざるをえないとおもいますが・・・
glad2121 @everpeace もちろん 2 はクラスじゃないよ。クラスは整数や実数です。で、例えば、整数クラスのインスタンスとしての2は概念的に1つか複数かという話。
everpeace @glad2121 では「概念」って何なのかを定義するひつようがありませんか??
everpeace @glad2121 整数のインスタンスのidentityについた名前じゃないですかね?2というのは。

glad2121 問題領域のモデリングで、たとえば顧客を Entity、生年月日(日付)を Value と分類したとして、Entity と Value の本質的な違いは何か? 顧客の住所を別クラスに抽出したとして、それは Entity? Value? どちらでもない?
kazumi007 @glad2121 むずかしいこと考えてますねー。EntityとValueの違いは、状態をもつかもたないか?という判断をしていますね。僕は。
tadayosi @glad2121 むしろGLADさんの方が解決領域の話をしているような。今「2」と発話したものと、今「2」と発話したものとが同じであるというのは、どういう根拠があってのものですか? 同値性の概念が(どんなものか分かりませんが)ないと、そういった判断はできないはずですよね?
everpeace @glad2121 なんていうか、identityというのはたくさんある要素を区別するためのラベルでしかないと思うのです。住所というのを、無数にある場所のラベルととらえるならそれはValueということでいいと僕は思います。
everpeace @glad2121 Valueというのは、要素のidentityに意味がある。Entityにはidentityより、identityによって区別さる要素の持つ付加情報に意味がある。な感じです。
tadayosi @glad2121 また、そもそもリンゴが2つあった場合の様態と、水が2リットルあった場合の様態と、文字で「2」と書いた場合の様態とで、そこには「2」という概念が共通して存在することをどうやって保証しますか?
everpeace @tadayoshi 保証する必要があるのでしょうか??@tadayoshiさんご自身がそれだけ「2」という同じ表現をつかっているのに。 保証されない場合にどんな不具合があるのでしょう?
everpeace @tadayoshi ちょっと僕の直前の発言なしで(苦笑

取り消す必要なかったと思うんですけどね。everpeaceさんの identity 論は僕の考えに近いです。

everpeace @tadayoshi @glad2121 例えば名前(氏(文字列)・名(文字列))がエンティティだって言っても、どこかでIdentityを実現するためにIdentityの表現があるはずです。その表現(たぶんValue)のクラスをIDと呼ぶと(続く)
everpeace @tadayoshi @glad2121 N=(ID,文字列,文字列)というクラスのインスタンスはその表現自身ですべての要素が区別されますから、その表現はValueといってもいいですよね??そんな感じですが、伝わりますでしょうか。(ここでは文字列はValueとしています)

それは違うと思います。ID と氏名の紐づけは自明じゃないから、何らかの方法で管理する必要があります。
さっきまでと Value の定義が変わっているような...

glad2121 @tadayosi リンゴの2個と水2リットルの2はクラスが違う気がしますが... それはさておき、果物屋さんのモデリングで、注文Aのリンゴ2個と出荷Aのリンゴ2個が同一であることは、モデルを共有している人の間の合意が基礎になるかな。
eeverpeace @glad2121 リンゴをモデリングするとします。モデリングするとは、そのリンゴ(物質としてのリンゴ)を、なんらかの性質の羅列によって表現することです。属性という言葉でいってもいいかもしれません。さて、リンゴをモデリングするとき(続く)
everpeace @glad2121 リンゴを「完璧」にモデリングできたとします。ここで「完璧」というのは、羅列された性質のうち一つでも変化することによってリンゴの同一性が変わってしまうようなモデリングができたとします。そのときこのモデリングValueといってもよいのでは?
everpeace @glad2121 完璧なモデリングが不完全だから、identityというのをつけて僕たちは「区別」するしか方法がないんじゃないでしょうか??

完璧なモデリングが不完全だからじゃなくて、複数のものを(特に時間軸上で)同一視するために identity という概念が生み出されたんじゃないでしょうか。

glad2121 @kazumi007 次の仕事がモデリングのコンサルなんで。(^^;) で、「状態」って何でしょう? 不変な属性も状態と呼んでいい?
everpeace @glad2121 たまたま「数」とか「量」という抽象的な概念はそれ自体がそもそもモデリングされるときの要素(僕たちが物の性質とい表すときに使うもの)だから、見えにくくなっているだけじゃないでしょうか?
everpeace @glad2121 人間が作り出したといってもいい。人間が作り出したものって大抵Valueじゃないでしょうか??本質的にEntityって物理的に存在する物質くらいだとおもうんですが。。。。

物理的に存在する物質の同一性もデカルトは疑ってますけどね。
everpeace のこの辺りの話は純粋関数型ですね。でも、昨日のAさんと明日のAさんは別人ですじゃ業務が回らない。

tadayosi @glad2121 「モデルを共有している人の間の合意」ということは、やはりValueになんらかの同一性(同値性)の判断は必要なんですよね? 現象としての「2」は、やはり複数のインスタンスをもつのではないですか?
glad2121 感覚的には、住所の定義が「ある地点を意味するラベル」だったら Value、「ある顧客の住所を記述する場所」だったら Entity に近いかな?
tadayosi @everpeace いちおう、僕は @tadayosi です。-shi ではなく -si。
everpeace @tadayosi 失礼しました><
glad2121 前者なら「港区芝浦2丁目」の 2丁目 を 3丁目 に書き換えちゃダメ、変えたら別インスタンスになる。後者なら書き換えてもいいけど、それを Value とは呼ばないでほしい。
everpeace 僕はこの世は全部Valueって言ったほうが好き。 Entityni
everpeace @glad2121 とすると、「顧客の住所を記憶する場所」としての住所と、地点を意味するラベルを表す住所はべつクラスとして定義すべきってことですか?僕ちょっとそれは違和感があります・・・
everpeace @glad2121 あくまで住所というのはValueで、顧客というインスタンスの属性としての住所ですね。だって同じ場所は同じ場所なんだもん。
everpeace @glad2121 さっきの注文Aの「2」と、注文Bの「2」というのは、僕たちが注文Aと注文Bというidentityのある2つのモノに含まれている「2」を見てるから違うように見えるけど、僕たちが実際に区別しているのは注文Aと注文Bで、そこに含まれる「2」という量は同じでいいと思う

tadayosi @kazumi007 ちなみに、DDDでは状態変化をしないEntityというのも存在します。例として、あるイベントの履歴みたいなものは、一意性はあるけれど状態変化しないものです。最近では、そういったものはEntityでもValueでもなく、Domain Eventと言うみたいです
glad2121 Value って他のオブジェクトにくっついて生きるコバンザメみたいなものか? (^^;)
kazumi007 @tadayosi ヘー、そういう概念があるんですね。ますます、わからなくなってきた。
everpeace @glad2121 まぁ、そういう言い方もできないこともないかもしれませんね^^; オブジェクトって、ずーーっとオブジェクトツリーを紐解いていくと、ツリーの葉っぱってValueになる気がしませんか??
everpeace @glad2121 って考えると、僕たちはValueをこねくり回して、identityという謎の性質を仮定してObjectというのを作り出しているだけのような気が。("a","a"),("a","a")を区別したいからidentityを無理やりくっ付けてObjectとしてみる的な
everpeace @glad2121 そして、そのidentityを実際に実現してるのは、結局Valueである1,2,3,...とかいう整数だったりするw

tadayosi DDDのValueで重要なのは、ライフサイクルを管理する必要がないってことなんだけどな。ライフサイクル管理をなるべく楽するために、EntityとValueの区別をした方がいい、という話なのだが。
everpeace V1,V2というvalueのクラスがあるとする。 全単射f: V1→V2という関数があったとき、fをidentityとして、V2型の一個のフィールドをもったオブジェクトが出来る。
everpeace @tadayosi ライフサイクルって何でしょうか??例えば(氏名)があったとき(山田太郎)さんも(こまたたまこ)さんも存在としては考えられますよね?名前空間として。その中で生起するかどうかって話ですか?それはValueも同じだと思うのですが。どういう意味でしょう?
yyamano それって一般的な定義?
yyamano 逆な気がする。
tadayosi @everpeace ちょっとよく分からない。ライフサイクルとは、それが生成されてから消滅するまでに一連の持続性があり、その持続性をなんらかの形で維持しなければいけないということ。(オレ定義)
glad2121 @tadayosi やっぱり不変性が重要なんですね。
glad2121 @everpeace Entity の属性って ("a","a") のように必ずしも明確に定義されていないと思います。識別子は定義されている必要がありますが、それ以外は隠蔽されていたり、追加/削除されることも。
everpeace @glad2121 属性の全く定義されてないEntityもありってことですか??それってどうやって等価性(equals()のやつ)を判断するんでしょうか??それはequalsの実装が決めればよいという感じですか?
umejava @glad2121 両者を区別することのメリットがよくわかりませんが、UMLのDataTypeの定義はこうですね"A data type is a type whose instances are identified only by their value."