不変クラスはサイコーだ!!!!
不変クラスとは?
簡単に言うと、インスタンスが変更できないクラス。
もっと正確に言うと、インスタンスが生成された時点で、全てのフィールドが固定されているクラス。
Javaから提供されているライブラリーのクラスで不変クラスは以下の通り。
- Stringクラス
- ボクシングされた基本データクラス
- BigIntegerクラス
- BigDecimal
不変クラスを提供するための5つの規則
1. オブジェクトのフィールドを変更するためのメソッドを提供しない。
いわゆるセッターメソッドを提供しない。
2. クラスが継承できないことを保証する。
継承できないやり方は2通りあり、一つがクラスをfinalにする方法。
もう一つがstaticファクトリーメソッドを提供する方法。
staticファクトリーメソッドの詳細は以下を見てもらえたら。
staticファクトリーメソッドの長所 その1
staticファクトリーメソッドの長所 その2
3. 全てのフィールドをfinalにする。
4. 全てのフィールドをprivateにする。
5. 可変オブジェクトのフィールドを保持しているならば、クライアントがそのオブジェクトを取得できないことを保証する。
このようなメソッドを防御的コピーと言う。
これはコードで説明したほうが早そうだな。
例えば、Dateクラスを保持しているフィールドがある場合は、以下のようなゲッターメソッドを提供すべき。
private final Date value; public Date getDate(){ new Date(value.getTime()); }
不変クラスのメリット
不変クラスの最大のメリットは、クライアント側が対象クラスの使い方を誤りにくく、安全に使用できる。という点。
後、対象クラス自体も、クラスが生成された時点で全てのフィールド値が固定されるので、設計・実装が可変クラスよりも簡単。
例えば、可変クラスの場合は、特定のフィールド値に依存したメソッドが提供されている場合、そのフィールド値がセットされているかどうかの判定処理を考慮する必要がある。それに比べて、不変クラスの場合は、このような考慮は不要である。
まとめ
限りなく100%の割合で、不変クラスを提供すべし。