

DDD本を読んでいて、オブジェクトはValue ObjectとEntity Objectに分けられ以下のように理解  
しました。、  
・Entity Object  
・不変な識別（IDなど）できるものがあり  
・その他の属性は変更可能  
・ValueObject  
・生成時のみ値を設定でき変更不可  
・同じオブジェクトを生成できる。  
  
この場合、例えばEntityObjectの属性にValueObjectがあった場合  
そのValueObjectの変更は不可能だと思うのですが、入れ替えることも  
できず、どうするのが良いのでしょうか？それとも使い方が間違っているのでしょうか？  
+++++++++++++++++++++++++  
以下思いつきで書いてみたので文法上間違いが多々あるかもわかりませんが、ソースコード書いてみました。

[code]

    public class ValueObject
    {
         private int b;
         ValueObject(int a)
         {
              b=a;
         }
         ValueObject multi(int a)
         {
             return new ValueObject(a*b);
         }
         ValueObject copy()
         {
             return new ValueObject(b);
         }
    }
    public class EntityObject
    {
          private final int id;
          private ValueObject vo;
          EntityObject(int id,int value)
          {
             this.id=id;
             vo = new ValueObject(30);
    
    
          }
          void setValue(int a)
          {
               //ここのやり方がわからない
          }
          ValueObject getValue()
          {
              return vo.copy();
          }
    }
    
[/code]


CC BY-SA 3.0
2015-10-06T00:06:22.147
17299
2015-10-06T03:58:39.990
2015-10-06T02:26:25.963
8000
12480
question
ドメイン駆動設計
value objectについて質問です。


下のようなイメージとなります。

[code]

        public class EntityObject
        {
              private final int id;
              private ValueObject vo;
              EntityObject(int id,ValueObject value)
              {
                 this.id=id;
                 vo = value;
              }
              void setValue(int a)
              {
                 vo = new ValueObject(a);
              }
              ValueObject getValue()
              {
                  return vo.copy();
              }
        }
    
[/code]

「ValueObjectの変更が不可能」というのは、`ValueObject`オブジェクトの属性`b`の値を変更することができない(ように実装する)、という意味です。

質問文中のコードは、`ValueObject`型属性の参照先を変更しないようにする意図があるように見えますが、そういうわけではありません。

> ・Entity Object  
>  ・不変な識別（IDなど）できるものがあり  
>  ・その他の属性は変更可能

と書かれている通り、変更は可能です。

* * *

以下、質問からは少し外れるのですが、実際には以下の様な形のsetter/getterになるのが自然かと思います。

[code]

              void setValue(ValueObject value)
              {
                 vo = value;
              }
              ValueObject getValue()
              {
                  return vo;
              }
    
[/code]

  * setする型とgetする型が揃っている
  * バリューオブジェクトは不変であるため必ずしも新しいインスタンスを生成する必要はない

という理由からです。


CC BY-SA 3.0
2015-10-06T03:58:39.990
17303
2015-10-06T03:58:39.990
2808
17299
answer