1. 程式人生 > >《Effective Java》讀書筆記 - 最小化類的可變性

《Effective Java》讀書筆記 - 最小化類的可變性

有效 down private 讀書筆記 工廠 public 限定 如果 構造器

Item 15 最小化類的可變性

effective java

如何做到讓類不可變?

  1. 不提供改變對象狀態的方法。(mutators)
  2. 確保類不會被繼承,即用final來限定類。
  3. 讓所有的域(field)為final。
  4. 讓所有的域private。
  5. 確保所有對可變組件的互斥訪問(Ensure exclusive access to any mutable components)

例子:

public final class Complex{
//final class

    private final double re;
    //private final field
    private
final double im; public Complex(double re,double im){ this.re = re; this.im = im; } public double realPart(){return re;} public double imaginaryPart(){return im;} public Complex add(Complex c){ return new Complex(re+c.re,im+c.im); //return new object instead of modify itself
} //Other arithmetic method ommit... }

為什麽要使用不可變對象(immutable objects)?

  1. 不可變對象很簡單。不需要考慮對象在變化中是否會變得行為怪異。只要在構造方法中有限制,不可變對象就一直是有效的。
  2. 不可變對象本質上是線程安全的,不需要同步(synchronization)。不可變對象是鼓勵共享而不用擔心安全。例如以下這種:

    public static final Complex ZERO = new Complex(0,0);
  3. 不可變對象的內部也是鼓勵共享的。
  4. 不可變對象作為其他復雜對象的構件(building blocks)是很優秀的。其不變的性質降低了復雜對象的設計難度。

不可變對象的缺點以及優化

  1. 不可變對象的唯一缺點:每次操作都需要創建新對象,在多步操作中造成性能問題。
  2. 優化:
    1. 在多步操作中使用可變的“伴隨類”(mutable "companion class")。例如String類與String Buffer類。
    2. 預測哪些多步操作是經常被使用的,提供這些操作的官方方法進行優化。

最佳實踐

  1. 提供公有的靜態工廠方法(static factory method)並讓構造器為私有。
    1. 可以提前檢測輸入數據的有效性,如果不合法可以直接避免創建對象。
    2. 可以緩存一些常用的對象,優化性能。
    3. 可以添加一些實用的功能。
  2. 制造不可變類的條件可以弱化為任何方法都不能造成對象外部表現的改變。這樣我們可以創造一些內部的可變組件用於緩存,進而優化性能。

總結

  1. 設計一個類時首先考慮是否能讓它不可變。
  2. 如果類不能做成完全不可變的,將其可變性限制到最低。
  3. 不要在靜態工廠方法和構造器之外提供任何的初始化方法。

《Effective Java》讀書筆記 - 最小化類的可變性