値オブジェクト
コンピュータサイエンスにおいて値オブジェクト(あたいオブジェクト、英語: Value object)は、同一性が識別子でなく属性によって決定されるオブジェクトのことをいう[1]。異なるオブジェクトであっても、それらを構成する値が等価であればそれらは等価であると見做される[1][2][3]。 値オブジェクトで表せるものとしては、数や色、日付、金額、文字列等が挙げられる[1]。 値オブジェクトはイミュータブルであることが望ましいとされる[4]。これは、等価なものとして生成されたオブジェクトは必ず等価性を維持することが期待されるためである。加えて、オブジェクトがイミュータブルであることによって、利用者側が一度生成されたオブジェクトを無効な状態へ変更することを防ぎ、クライアントコードにおけるバギーな挙動を防ぐことができるとされる[5]。 これらの特徴により、概念的には等価である複数のオブジェクトを値オブジェクトとして得ることができる。値オブジェクトが用いられるような対象においては、単一のインスタンスの参照を使い回すよりは、新しいオブジェクトを生成する方が簡単な場合が多い[6]。 値オブジェクトは、ドメイン駆動設計におけるドメインモデルの構成要素の1つでもある。 定義ダーク・リールら(1988)は、値(Value)を以下のように定義し、これをクラスで実装したものを値オブジェクトと呼んだ[7][3]。
また、仙塲大也は値オブジェクトを以下のように定義している。
一方でこの定義に対しては、本質的に重要なのは値の定義であり、実装は必ずしもクラスである必要はなく、「値をクラスによって設計すれば、それは値オブジェクトという設計パターンになる」という誤解を招く記述であるという批判がある[3]。 実装値オブジェクトは一般に等価性を判定するメソッドを持つ。例えばPythonの整数型であれば、 さまざまなオブジェクト指向プログラミング言語のニュアンスにより、それぞれに値オブジェクトを実装および使用するための独自のメソッドとパターンがある。 C#C#では、クラスは参照型であり、構造体( C言語の構造体から派生した概念)は値型である [8]。したがって、クラス定義から派生したインスタンスはオブジェクトであり、構造体定義から派生したインスタンスは値オブジェクトと呼ばれる(正確には、構造体をイミュータブルにして、属性を読み取り専用として宣言する事で値オブジェクトを表現することができる[9] )。 次の手順を実行することによって、C#クラスを値オブジェクトとして扱うことができる。
あるいは、C# 9.0で追加されたレコード[12]も値オブジェクトとなる型の作成に使用できる[13]。 C++C++では、代入演算子をオーバーロードし、フィールド(コンストラクターの初期化子リストによって一度だけ評価される)とクラスのメソッドに適切なconst制約を使用することで値オブジェクトを構築できる。 ただし、フィールド自体をconstとして宣言した場合(つまり非constフィールドとgetterの組み合わせで実現する方法でなかった場合)、そのような値オブジェクトは別の値オブジェクトで完全に上書きすることは不可能となる( JavaC#やC++とは異なり、Javaは言語レベルでのカスタム値型をサポートしていない。カスタム値型のサポートの拡張は検討されているが[14]、すべてのカスタム型は参照型であるため、同一性と参照のセマンティクスを持つ[15]。 したがって、Javaプログラマーは、イミュータブルなオブジェクトを作成することによって値オブジェクトをエミュレートする事になる[16]。オブジェクトの状態が変わらない限りにおいて、参照を渡すことは、値オブジェクトをコピーすることと意味的に同等となるからである。 すべての属性を空白のfinal [17]として宣言し、すべての属性をArrayListまたはDateのような可変タイプのような可変タイプではなく不変タイプ(たとえば、String、Integer、またはこれらの規則に従って宣言された他のタイプ)とする。また、参照ではなく値を比較するために、equalsとhashCodeを定義するべきである。 「VALJO」(VALue Java Object)という用語は、正しく定義されたイミュータブルなあたいオブジェクトに必要な、より厳密なルールのセットを指すために作られた[18]。 値オブジェクトは、Java14以降データレコードとして使用可能である[19]。 例public class StreetAddress
{
public StreetAddress(string street, string city)
{
Street = street;
City = city;
}
public final string Street { get; }
public final string City { get; }
}
関連項目参考文献
|
Portal di Ensiklopedia Dunia