Value object

コンピュータサイエンスでは、Value Object（値オブジェクト）は、同等性がアイデンティティに基づいていない単純なエンティティを表す小さなオブジェクトである。つまり、2つの値オブジェクトは、同じ値を持つ場合は等しく、必ずしもそれらが同一のオブジェクトである必要はない。

値オブジェクトの例としては、金額や日付範囲を表すオブジェクトなどが挙げられる。

小さいので、同じエンティティを表す同じ値オブジェクトの複数のコピーを持つことが可能である。単一のインスタンスに依存してそのオブジェクトを共有するよりも、新しいオブジェクトを作成する方が簡単な場合がよくある。

値オブジェクトは不変である事が好ましい：これは、2つの値オブジェクトが等しく作成され、等しいままであるという暗黙の前提に必要となる。クライアントコードが値オブジェクトを無効な状態にしたり、インスタンス化の後にバグのある挙動を導入したりできないようにする点でも有用である。

値オブジェクトは、DDDの構成要素の1つでもある。

実装 
さまざまなオブジェクト指向プログラミング言語のニュアンスにより、それぞれに値オブジェクトを実装および使用するための独自のメソッドとパターンがある。

C＃ 
C＃では、クラスは参照型であり、構造体（ C言語の構造体から派生した概念）は値型である。 したがって、クラス定義から派生したインスタンスはオブジェクトであり、構造体定義から派生したインスタンスはValue Objectと呼ばれる（正確には、構造体を不変にして、属性を読み取り専用として宣言する事でValue Objectを表すことができる ）。

次の手順を実行して、値オブジェクトの特性をC＃クラスに追加できる。

 をオーバーライドして、オブジェクトがビジネスロジックを使用して比較されることを保証する。
 メソッドが使用されるように、デフォルトの動作およびを演算子オーバーロードする。
  メソッドをオーバーライドして、等価性を持つオブジェクトのハッシュが同じとなるようにする。
 プロパティセッターを削除し、コンストラクターを介してのみメンバー値を渡すことにより、クラスを不変にする 。

あるいは、C# 9.0で追加されたレコードも値オブジェクトとなる型の作成に使用できる。

C++ 
C++では、代入演算子をオーバーロードし、フィールド（コンストラクターの初期化子リストによって一度だけ評価される）とクラスのメソッドに適切なconst制約を使用することで値オブジェクトを構築できる。

ただし、フィールド自体をconstとして宣言した場合（つまり非constフィールドとgetterの組み合わせで実現する方法でなかった場合）、そのようなValue Objectは別のValue Objectで完全に上書きすることは不可能となる（  ）。

Java 
C＃やC++とは異なり、Javaは言語レベルでのカスタム値型をサポートしていない。カスタム値型のサポートの拡張は検討されているが、すべてのカスタム型は参照型であるため、同一性と参照のセマンティクスを持つ。 

したがって、Javaプログラマーは、不変オブジェクトを作成することによって値オブジェクトをエミュレートする事になるオブジェクトの状態が変わらない限りにおいて、参照を渡すことは、Value Objectをコピーすることと意味的に同等となるからである。

すべての属性を空白のfinal として宣言し、すべての属性をまたはのような可変タイプのような可変タイプではなく不変タイプ（たとえば、、、またはこれらの規則に従って宣言された他のタイプ）とする。また、参照ではなく値を比較するために、equalsとhashCodeを定義するべきである。

「VALJO」（VALue Java Object）という用語は、正しく定義された不変Value Objectに必要な、より厳密なルールのセットを指すために作られた。 

値オブジェクトは、Java14以降データレコードとして使用可能である

例 
public class StreetAddress
{
    public StreetAddress(string street, string city)
    {
        Street = street;
        City = city;
    }

    public final string Street { get; }
    public final string City { get; }
}

関連項目 

 データ転送オブジェクト
 ドメイン駆動設計
 値 (計算機科学)

参考文献 

オブジェクト (計算機科学)