独書会 Scala IN DEPTH @大人の喫茶店 その2で記述した、第2章 The core rules の続き。
要約
不変性を選ぶ
- 不変性は、オブジェクトを生成した後に状態を変えないこと。
- 関数型プログラミングの優れた特徴の1つであるけど、オブジェクト指向設計のオススメのプラクティスでもある。
- Scalaでも多くのケースで、デフォルトで不変性になる。
- 不変性は特に equality issues と concurrent program で役に立つ。
- immutable object と immutable reference は違う。
immutable reference
- Scalaでは全ての変数が、オブジェクトへの参照。
-
val
で変数定義することは、 immutable reference であることを指す。 - 全てのメソッドパラメータは、 immutable references である。
- クラスの引数はデフォルトでは、 immutable references である。
- mutable変数を作るための方法の一つが、
var
シンタックス。。 - 参照の不変性は、参照されるオブジェクトがimmutableかどうかは関係ない。
- immutable objectのためのmutable referenceを持てる。
- mutable objectのためのimmutable referenceを持てる。
- オブジェクト自体がimmutable or mutableなのかを知ることが重要であることを意味している。
オブジェクトの不変性の制約の定義
- 定義は明らかになっていない。
- 一般的にドキュメントが述べているなら、オブジェクトはimmutableと仮定しても安全であり、それ以外の場合は注意が必要。
- Scala標準ライブラリでは、パラレルパッケージ階層とimmutable class, mutable classを持つことによりコレクションクラス内での線引を明確にしている。
- 不変性の利点は、equality issueとconcurrent programで顕著になる。
オブジェクトのequality
- 不変性はオブジェクトのequalityを簡略化する。
- ライフサイクルの中でオブジェクトが状態変化がなければ、深さと正確さの両方でを満たす等価の実装を作ることができる。
- これは
hash
関数を作るときにも重要で、hash
関数はオブジェクトの簡略された表現を返すものであり、通常はInteger
である。すばやくオブジェクトの識別をするために使われる。 -
hash
関数はequals
メソッドとペアにするべき。 - オブジェクトの状態が変化した時、hashコードは壊れる。
Scalaでのequalityの実装
Scalaではjava.lang.Object
で定義されたequals
hashCode
メソッドを利用する。
- primitiveオブジェクトは、
scala.AnyVal
のサブタイプである。 - 一方、
java.lang.Object
を拡張している標準objectは、scala.AnyRef
のサブタイプである。 -
scala.AnyRef
はjava.lang.Object
のためのエイリアスと考えるられる。 -
hasCode
とequals
は、AnyRef
で定義している。メソッド##
==
で提供していて、AnyRef
AnyVal
の両方で使える。 -
hasCode
とequals
は、常に実装するべき。例えば、x == y
ならx.## == y.##
。
equalityの実装制約
equalityは以下の実装を取り入れる。そしてこの制約を満たすのが immutable object。
- 2つのオブジェクトが等しい場合は、同じ
hashCode
を持つべき - オブジェクトのために計算された
hashCode
は、オブジェクトのライフサイクルで変更しない - 別のJVMにオブジェクトを送るとき、equalityは両方のJVMで利用できる属性であるべき
1つ目、2つ目の制約を満足させる簡単な方法が、2つある。
-
hashCode
の計算内ではimmutable objectの内部状態のみを利用する -
equals
とhashCode
のために、デフォルトの概念を使う
オブジェクト内に存在するモノはimmutableでなければ いけない 。
全てのobjectをimmutableにすることは、プロセス全体を簡素化する。
Concurrency
- 不変性はconcurrentのデータアクセスを単純化する。
- concurrent threadでの実行の必要性が高まっている。
- スレッド間でのデータ共有の手段が必要。
- 伝統的な手段は、mutable dataを守るためlockの仕組み。
- 不変性だとlockを減らして状態の共有ができる。
- lockはパフォーマンスのオーバヘッドを生じる。
Rule
3. 不変性を選ぶ
- immutable classを作ることは、潜在的な実行時の問題をドラスティックに減らす。
所感
- immutable objectは安全性を高めれる。関数型プログラミングに馴れるための最初の一歩として、immutable objectを使い続けてみるのが良さそう。
- 所謂 情報保持役 のオブジェクトに関しては、
##
と==
メソッドを実装した方が良いのは、Javaと変わらない。