楽水

人々の創造が自由に表現できる舞台づくり

アプリケーション デザインパターン

オブジェクトの性質【同一性、等価性、不変性、参照透過性】

投稿日:2021年7月12日 更新日:


ここでは、オブジェクトの性質について、以下の観点で解説します。

  • 同一性
  • 等価性
  • 不変性
  • 参照透過性
  • 同一性と等価性
  • 同一性と不変性
  • 不変性と参照透過性
  • 参照オブジェクトと値オブジェクト
  • 参照型と値型

同一性

オブジェクトが同一(identical)とは、オブジェクトが時や場所を越えてそれ自身に同じであることです。
これは、個々のオブジェクトがID(identifier:識別子)を持つことを意味します。
同一性(identity)とは、オブジェクトが持つ、同一であるかどうかを示す性質のことです。
同一性を持つオブジェクトはコピーできません。
ソフトウェア開発で、問題領域(ドメイン)に存在するオブジェクトを分析するときに重要な観点は、オブジェクトの同一性を意識するかどうかです。

等価性

オブジェクトが等価(equivalent)とは、オブジェクトの値が等しいいことです。
これは、オブジェクトの持つ状態変数の値が等しいことを意味します。
等価性(equivalence)とは、オブジェクトが持つ、等価かどうかを示す性質のことです。
ソフトウェア開発で、問題領域(ドメイン)に存在するオブジェクトを分析するときに重要な観点は、オブジェクトの等価性を意識するかどうかです。

不変性

オブジェクトが不変(immutable)とは、オブジェクトが値を変えないことです。
これは、個々のオブジェクトが状態(状態変数の値)を変えないことを意味します。
逆に、可変(mutable)なオブジェクトは、状態を変えていきます。
不変性(Invariant)とは、オブジェクトが持つ、不変かどうかを示す性質のことです。
ソフトウェア開発で、問題領域(ドメイン)に存在するオブジェクトを分析するときに重要な観点は、オブジェクトの不変性を意識するかどうかです。
可変なオブジェクトが状態を変える性質を連続性といいます。

参照透過性

Wikipediaでは、参照透過性(referential transparency)について次のように説明しています。

ある式が参照透過であるとは、その式をその式の値に置き換えてもプログラムの振る舞いが変わらない、言い換えれば、
同じ入力に対して同じ作用と同じ出力とを持つプログラムになる
ことを言う。
具体的には変数の値は最初に定義した値と常に同じであり、関数は同じ変数を引数として与えられれば同じ値を返すということになる。
参照透過性が成り立っている場合、ある式の値、例えば関数値、変数値についてどこに記憶されている値を参照しているかということは考慮する必要がない、即ち参照について透過的であるといえる。

複数の機器やソフトウェア、システムなどを連携して動作させる際に、ある構成要素の存在を意識しなくてもその機能を有効にすることができること透過的(transparent)といい、透過的な性質を透過性(transparency)といいます。
transparentには、透明な、透き通るという意味だけではなく、その結果、明白な、わかりやすいという意味があります。
透過的とは、複数の機器やソフトウェア、システムなどを連携して動作させる際、ある構成要素の存在を意識して、その機能を使うより、存在を意識しなくても使えた方が、機能を使う側から見て、その機能がシンプルで(複雑ではなく)わかりやすいという意味です。
例えば、使う側が、暗号化してからファイルを保存しなければならないシステムより、ファイルを保存すれば自動的に暗号化してくれるシステムの方がシンプルでわかりやすいですよね。
以上より、オブジェクトの参照透過性とは、っクラスのメソッドが、変数値についてどこに記憶されている値を参照しているか意識しなくても、常に同じ入力に対して同じ結果を出力するかどうかという、オブジェクトの持つ性質のことと考える。

プログラミングにおける副作用

関数やメソッドの主な作用は、引数を受け取り値を返すことで評価値を得ることですが、これ以外に、コンピュータの論理的状態(ローカル環境以外の状態変数の値)を変化させる作用を、プログラミングにおける副作用といいます。
プログラミングにおける副作用は、コンピュータの論理的状態を変化させるので、それ以降で得られる処理の結果に影響を与えます。
なので、副作用は、予期せぬエラーを発生させるリスクとなり、それを下げるため以下のようなコストを発生させ、結果的に、ソフトウェアの保守性を下げることになります。

  • 副作用によってどこに影響があるか調査しなければならない
  • その影響によって、動作に支障が出ないようにしなければならない

また、副作用が起こるクラスなどのソフトウェアの構成要素は、常に同じ結果を提供するわけではないので、交換可能な部品としてのモジュール性、再利用性が低くなります。
参照透過なメソッドや関数の場合、コンピュータの論理的状態(ローカル環境以外の状態変数の値)を変化させないので、副作用を起こすことはなく、ソフトウェアの保守性や再利用性を確保することができます。

同一性と等価性

オブジェクトにおける同一性と等価性の関係ですが、以下のように論理包含の関係になります。

つまり、同一(IDが同じ)ならば等価(値も同じ)という論理関係です。
同一(IDは同じ)だけど等価でない(値は違う)という状況はありません。

同一性と不変性

オブジェクトを同一性と不変性の観点から以下のように分類することができます。

  • 同一性を持つ(IDがありコピーできない)
    同じ初期値を持つオブジェクトを複数生成することは不可能。

    • 不変性がある
      初期値を変えることができない。
      NFT(Non-Fungible Token、非代替性トークン)が該当すると考えられます。
    • 不変性がない
      初期値を変えることができる。
      後述する参照オブジェクト(エンティティ)が該当します。
  • 同一性をを持たない(IDがなくコピーできる)
    同じ初期値のオブジェクトを複数生成することが可能。

    • 不変性がある
      初期値を変えることができない。
      後述する値オブジェクトが該当します。
    • 不変性がない
      初期値を変えることができる。
      生命現象?

不変性と参照透過性

不変性を持つオブジェクトを不変オブジェクト、不変性を持たない(状態を変える)オブジェクトを可変オブジェクトといいます。
不変オブジェクトと可変オブジェクの特徴は以下のようになります。

  • 不変オブジェクト(immutable object)
    不変オブジェクトの場合、変数の値は最初に定義した値と常に同じなので、メソッドは同じ変数を引数として与えられれば同じ値を返す。
    なので、クラスのメソッドが、変数値についてどこに記憶されている値を参照しているか意識する必要はなく参照透過である
    不変オブジェクトの場合、それに対する参照が異なっても(同じであっても)、等価なオブジェクトのクラスのメソッドは、同じ変数を引数として与えられれば同じ値を返す。
    ※この場合の参照とは、他の場所にあるデータ(オブジェクト含む)を指している情報を含む小さなオブジェクトのこと。
  • 可変オブジェクト(mutable object)
    可変オブジェクトの場合、変数の値は最初に定義した値と常に同じとは限らないなので、メソッドは同じ変数を引数として与えられれば同じ値を返すとは限らない。
    なので、可変オブジェクトの場合、どの変数値を参照しているか考慮する必要があるので参照透過ではない

参照オブジェクトと値オブジェクト

参照オブジェクト(エンティティ)と値オブジェクトの特徴をまとめると以下のようになります。

  • 参照オブジェクト(エンティティ)
    • 同一性
      同じオブジェクトは同一(同じIDを持つ)である。
    • 連続性
      可変(mutable)である。
    • 参照透過性
      参照透過でない。
  • 値オブジェクト

    • 等価性
      同じオブジェクトは等価(値が同じ)である。
    • 不変性
      不変(immutable)である。
    • 参照透過性
      参照透過である。

参照型と値型

  • 参照型
    参照型は、変数や定数に代入されるときや関数に渡されるとき、同じインスタンスの参照が渡される。
  • 値型
    値型は、変数や定数に代入されるとき、あるいは関数に渡されるとき、値がコピーされる。

-アプリケーション, デザインパターン

執筆者:


  1. […] ている値を参照しているか意識しなくても、常に同じ入力に対して同じ結果を出力すること。 同一性、連続性、等価性、参照透過については、オブジェクトの性質を参照してください。 […]

関連記事

MVC vs MVVM

ここでは、MVCとMVC2の違いについて以下の観点で解説します。 MVCとは何か MVVMとは何か MVC vs MVVM MVCについて詳しく知りたいかたは、 MVCとは【本来の仕組を詳しく解説】 …

MVC vs MVC2

ここでは、MVCとMVC2の根本的な違いを知りたいという方を対象に、 MVCとMVC2の違いについて以下の観点で解説します。 MVCとは何か MVC2とは何か MVC vs MVC2 MVCについて詳 …

ソフトウェアの設計原則②コマンド・クエリ分離の原則(CQS)

ソフトウェアの設計原則①:SOLIDの原則という記事で、変化に強いソフトウェアの代表的な特徴として以下をあげ、それを実現する、ソフトウェアの設計原則の一つ、SOLIDについて解説しました。 保守性が高 …

ドメイン駆動設計入門【DDDをわかりやすく解説】

突然ですが、エンジニアの皆さま、Javaで開発したWebアプリケーションの構成、このようになっていませんか? データとgetter/setterだけのオブジェクト(JavaBean) 画面のコントロー …

ソフトウェアの設計原則③GRASP

ソフトウェアの設計原則①:SOLIDの原則という記事で、変化に強いソフトウェアの代表的な特徴 保守性が高いこと 修正箇所が局所化され、他の部分に影響しないこと(リスクの局所化)。 再利用性が高いこと …