コンテンツにスキップ

値オブジェクト

出典: フリー百科事典『ウィキペディア(Wikipedia)』
Value objectから転送)

コンピュータサイエンスにおいて値オブジェクト(あたいオブジェクト、英語: Value object)は、同一性識別子でなく属性によって決定されるオブジェクトのことをいう[1]。異なるオブジェクトであっても、それらを構成する値が等価であればそれらは等価であると見做される[1][2][3]

値オブジェクトで表せるものとしては、日付金額文字列等が挙げられる[1]

値オブジェクトはイミュータブルであることが望ましいとされる[4]。これは、等価なものとして生成されたオブジェクトは必ず等価性を維持することが期待されるためである。加えて、オブジェクトがイミュータブルであることによって、利用者側が一度生成されたオブジェクトを無効な状態へ変更することを防ぎ、クライアントコードにおけるバギーな挙動を防ぐことができるとされる[5]

これらの特徴により、概念的には等価である複数のオブジェクトを値オブジェクトとして得ることができる。値オブジェクトが用いられるような対象においては、単一のインスタンスの参照を使い回すよりは、新しいオブジェクトを生成する方が簡単な場合が多い[6]

値オブジェクトは、ドメイン駆動設計におけるドメインモデルの構成要素の1つでもある。

定義

[編集]

ダーク・リールら(1988)は、(Value)を以下のように定義し、これをクラスで実装したものを値オブジェクトと呼んだ[7][3]

  • 問題領域における抽象概念をモデル化した(一般的で概念的な)抽象的存在で
  • ライフサイクル英語版を持たず(つまり、時間軸で存在せず、作成されたり変更されたり削除されたりしない)
  • 変更可能な状態を持たず(表象は解釈されるだけで変更されない)
  • 参照透過性を持つ(つまり、システムの他の箇所から値を利用したときの副作用がない)
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

また、仙塲大也は値オブジェクトを以下のように定義している。

値オブジェクト(Value Object)とは、値をクラス(型)として表現する設計パターンです。
仙塲大也、良いコード/悪いコードで学ぶ設計入門 ―保守しやすい 成長し続けるコードの書き方

一方でこの定義に対しては、本質的に重要なのは値の定義であり、実装は必ずしもクラスである必要はなく、「値をクラスによって設計すれば、それは値オブジェクトという設計パターンになる」という誤解を招く記述であるという批判がある[3]

実装

[編集]

値オブジェクトは一般に等価性を判定するメソッドを持つ。例えばPythonの整数型であれば、__eq__()メソッドを持つ。一方で、必ずしも値オブジェクトがequalメソッドを持つ必要はなく、等しさの概念が担保されていれば良いという見解も存在する[3]

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

C#

[編集]

C#では、クラス参照型であり、構造体( C言語の構造体から派生した概念)は値型である [8]。したがって、クラス定義から派生したインスタンスはオブジェクトであり、構造体定義から派生したインスタンスは値オブジェクトと呼ばれる(正確には、構造体をイミュータブルにして、属性を読み取り専用として宣言する事で値オブジェクトを表現することができる[9] )。

次の手順を実行することによって、C#クラスを値オブジェクトとして扱うことができる。

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

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

C++

[編集]

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

ただし、フィールド自体をconstとして宣言した場合(つまり非constフィールドとgetterの組み合わせで実現する方法でなかった場合)、そのような値オブジェクトは別の値オブジェクトで完全に上書きすることは不可能となる( object1 = object2 )。

Java

[編集]

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

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

すべての属性を空白のfinal [17]として宣言し、すべての属性をArrayListまたはDateのような可変タイプのような可変タイプではなく不変タイプ(たとえば、StringInteger、またはこれらの規則に従って宣言された他のタイプ)とする。また、参照ではなく値を比較するために、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; }
}

関連項目

[編集]

参考文献

[編集]
  1. ^ a b c Value Object”. Portland Pattern Repository's Wiki. Cunningham & Cunningham, Inc. (c2.com). 6 September 2012閲覧。
  2. ^ Fowler, Martin (2003年). “Value Object”. Catalog of Patterns of Enterprise Application Architecture. Martin Fowler (martinfowler.com). 17 July 2011閲覧。
  3. ^ a b c d 値オブジェクトへの誤解が生まれる一つのストーリー - 文脈と定義を大事にする”. Zenn (2022年8月18日). 2025年1月11日閲覧。
  4. ^ Value Object Should be Immutable”. Portland Pattern Repository's Wiki. Cunningham & Cunningham, Inc. (c2.com). 6 September 2012閲覧。
  5. ^ Burns. “The Value of a Value Object”. sam-burns.co.uk. 20 April 2015閲覧。
  6. ^ Value Object”. Portland Pattern Repository's Wiki. Cunningham & Cunningham, Inc. (c2.com). 6 September 2012閲覧。
  7. ^ Ubilab Technical Report, Values in Object Systems Want Value Objects in Java?” (1998年10月10日). 2025年1月13日閲覧。
  8. ^ Classes and Structs (C# Programming Guide)”. Microsoft Developer Network (msdn.microsoft.com) (2012年). 5 September 2012閲覧。
  9. ^ Creating an immutable value object in C# - Part III - Using a struct”. Luca Bolognese's WebLog (2012年). 7 September 2012閲覧。
  10. ^ Koirala. “Immutable objects in C# - CodeProject”. www.codeproject.com. 2017年12月26日閲覧。
  11. ^ koirala. “Value Object Design Pattern in C#”. www.codeproject.com. 2017年12月26日閲覧。
  12. ^ レコード - C# リファレンス”. Microsoft Docs. 2022年5月22日閲覧。
  13. ^ TillW. “DDD Value Objects as C# Records: The Missing Manual”. DEV Community. 2022年5月22日閲覧。
  14. ^ JEP 169: Value Objects”. 7 October 2015閲覧。
  15. ^ Java Language Specification, chapter 4. Types, Values, and Variables”. 7 October 2015閲覧。
  16. ^ Immutable objects”. Collected Java Practices (2012年). 5 September 2012閲覧。
  17. ^ hence assignable only in the constructors
  18. ^ VALJOs - Value Java Objects”. 19 October 2014閲覧。
  19. ^ Records Come to Java”. 13 April 2021閲覧。