値オブジェクト
この項目は内容が専門的であり、一般の閲覧者にはわかりにくくなっているおそれがあります。 |
コンピュータサイエンスにおいて値オブジェクト(あたいオブジェクト、英語: Value object)は、同一性が識別子でなく属性によって決定されるオブジェクトのことをいう[1]。異なるオブジェクトであっても、それらを構成する値が等価であればそれらは等価であると見做される[1][2]。
値オブジェクトで表せるものとしては、数や色、日付、金額、文字列等が挙げられる[1]。
値オブジェクトはイミュータブルであることが望ましいとされる[3]。これは、等価なものとして生成されたオブジェクトは必ず等価性を維持することが期待されるためである。加えて、オブジェクトがイミュータブルであることによって、利用者側が一度生成されたオブジェクトを無効な状態へ変更することを防ぎ、クライアントコードにおけるバギーな挙動を防ぐことができるとされる[4]。
これらの特徴により、概念的には等価である複数のオブジェクトを値オブジェクトとして得ることができる。値オブジェクトが用いられるような対象においては、単一のインスタンスの参照を使い回すよりは、新しいオブジェクトを生成する方が簡単な場合が多い[5]。
値オブジェクトは、ドメイン駆動設計におけるドメインモデルの構成要素の1つでもある。
定義
[編集]ダーク・リールら(1988)は、値(Value)について、以下の四つの主要な性質を持つものとした[6]。
- 問題領域における抽象概念をモデル化した(一般的で概念的な)抽象的存在で
- ライフサイクルを持たず(時間軸で存在せず、作成されたり変更されたり削除されたりしない)
- 変更可能な状態を持たず(表象は解釈されるだけで変更されない)
- 参照透過性を持つ(つまり、システムの他の箇所から値を利用したときの副作用がない) — Dirk Bäumer, Dirk Riehle, Wolf Siberski, Carola Lilienthal, Daniel Megert, Karl-Heinz Sylla, and Heinz Züllighoven. 、Values in Object Systems. Ubilab Technical Report
リールらは、この「値」を表現する値型はプログラミング言語においてプリミティブ型として提供され、言語としての用意がない場合はこれをクラスで実装する必要があるものとした[6]。
実装
[編集]値オブジェクトは一般に等価性を判定するメソッドを持つ。例えばPythonの整数型であれば、__eq__()メソッドを持つ。
さまざまなオブジェクト指向プログラミング言語のニュアンスにより、それぞれに値オブジェクトを実装および使用するための独自のメソッドとパターンがある。
C#
[編集]C#では、クラスは参照型であり、構造体( C言語の構造体から派生した概念)は値型である [7]。したがって、クラス定義から派生したインスタンスはオブジェクトであり、構造体定義から派生したインスタンスは値オブジェクトと呼ばれる(正確には、構造体をイミュータブルにして、属性を読み取り専用として宣言する事で値オブジェクトを表現することができる[8] )。
次の手順を実行することによって、C#クラスを値オブジェクトとして扱うことができる。
Object.Equalsをオーバーライドして、オブジェクトがビジネスロジックを使用して比較されることを保証する。Equalsメソッドが使用されるように、デフォルトの動作==および!=を演算子オーバーロードする。Object.GetHashCodeメソッドをオーバーライドして、等価性を持つオブジェクトのハッシュが同じとなるようにする。- プロパティセッターを削除し、コンストラクターを介してのみメンバー値を渡すことにより、クラスを不変にする[9] [10]。
あるいは、C# 9.0で追加されたレコード[11]も値オブジェクトとなる型の作成に使用できる[12]。
C++
[編集]C++では、代入演算子をオーバーロードし、フィールド(コンストラクターの初期化子リストによって一度だけ評価される)とクラスのメソッドに適切なconst制約を使用することで値オブジェクトを構築できる。
ただし、フィールド自体をconstとして宣言した場合(つまり非constフィールドとgetterの組み合わせで実現する方法でなかった場合)、そのような値オブジェクトは別の値オブジェクトで完全に上書きすることは不可能となる( object1 = object2 )。
Java
[編集]C#やC++とは異なり、Javaは言語レベルでのカスタム値型をサポートしていない。カスタム値型のサポートの拡張は検討されているが[13]、すべてのカスタム型は参照型であるため、同一性と参照のセマンティクスを持つ[14]。
したがって、Javaプログラマーは、イミュータブルなオブジェクトを作成することによって値オブジェクトをエミュレートする事になる[15]。オブジェクトの状態が変わらない限りにおいて、参照を渡すことは、値オブジェクトをコピーすることと意味的に同等となるからである。
すべての属性を空白のfinal [16]として宣言し、すべての属性をArrayListまたはDateのような可変タイプのような可変タイプではなく不変タイプ(たとえば、String、Integer、またはこれらの規則に従って宣言された他のタイプ)とする。また、参照ではなく値を比較するために、equalsとhashCodeを定義するべきである。
「VALJO」(VALue Java Object)という用語は、正しく定義されたイミュータブルなあたいオブジェクトに必要な、より厳密なルールのセットを指すために作られた[17]。
値オブジェクトは、Java14以降データレコードとして使用可能である[18]。
例
[編集]public class StreetAddress
{
public StreetAddress(string street, string city)
{
Street = street;
City = city;
}
public final string Street { get; }
public final string City { get; }
}
関連項目
[編集]参考文献
[編集]- ^ a b c “Value Object”. Portland Pattern Repository's Wiki. Cunningham & Cunningham, Inc. (c2.com). 2012年9月6日閲覧。
- ^ Fowler, Martin (2003年). “Value Object”. Catalog of Patterns of Enterprise Application Architecture. Martin Fowler (martinfowler.com). 2011年7月17日閲覧。
- ^ “Value Object Should be Immutable”. Portland Pattern Repository's Wiki. Cunningham & Cunningham, Inc. (c2.com). 2012年9月6日閲覧。
- ^ Burns. “The Value of a Value Object”. sam-burns.co.uk. 2015年4月20日閲覧。
- ^ “Value Object”. Portland Pattern Repository's Wiki. Cunningham & Cunningham, Inc. (c2.com). 2012年9月6日閲覧。
- ^ a b “Ubilab Technical Report, Values in Object Systems Want Value Objects in Java?”. p. 14 (1998年10月10日). 2025年1月13日閲覧。
- ^ “Classes and Structs (C# Programming Guide)”. Microsoft Developer Network (msdn.microsoft.com) (2012年). 2012年9月5日閲覧。
- ^ “Creating an immutable value object in C# - Part III - Using a struct”. Luca Bolognese's WebLog (2012年). 2012年9月7日閲覧。
- ^ Koirala. “Immutable objects in C# - CodeProject”. www.codeproject.com. 2017年12月26日閲覧。
- ^ koirala. “Value Object Design Pattern in C#”. www.codeproject.com. 2017年12月26日閲覧。
- ^ “レコード - C# リファレンス”. Microsoft Docs. 2022年5月22日閲覧。
- ^ TillW. “DDD Value Objects as C# Records: The Missing Manual”. DEV Community. 2022年5月22日閲覧。
- ^ “JEP 169: Value Objects”. 2015年10月7日閲覧。
- ^ “Java Language Specification, chapter 4. Types, Values, and Variables”. 2015年10月7日閲覧。
- ^ “Immutable objects”. Collected Java Practices (2012年). 2012年9月5日閲覧。
- ^ hence assignable only in the constructors
- ^ “VALJOs - Value Java Objects”. 2014年10月19日閲覧。
- ^ “Records Come to Java”. 2021年4月13日閲覧。