2020/07/16

[筆記] Effective Java #15 使 class 及其成員的可訪問性最小化

Effective Java 3rd 簡體中文版筆記 #15 使類及其成員的可訪問性最小化
設計良好的模組會將 API 及實作清楚的隔離,模組之間用 API 來溝通,一個模組不需要知道其它模組的實作細節,概念稱為訊息隱藏 (information hiding)封裝 (encapsulation)。訊息隱藏可以讓模組間解耦 (decouple),讓模組能單獨開發、測試、修改及優化等等。
Java 在訊息隱藏上包含訪問機制 (access control) 決定 class 及其成員的可訪問性 (accessibility),關鍵字為 private、protected、public。規則是盡量讓每個 class 及其成員不被外界訪問,使用最低級別。
一般的 class 及介面有兩種級別:package-private 及 public。package-private 是不釋出的部份,而 public 為 API 使用者可以訪問的,所以必須維護其兼容性。如果一個 package-private class 只在某個 class 中使用,那可以考慮將它變成該 class 的 inner class,但整體上減少 public class 的訪問性,比上述還要重要。

下面列出 4 種級別,依序為存取性弱到強:
  1. private:只有該 class 內的成員可以存取。
  2. package-private (default):預設,同一 package 內的 class 皆能存取。
  3. protected:package 內的 class 可以存取,繼承該 class 的 subclass 亦能。
  4. public:任何 class 皆能存取。
在編寫程式碼時,訪問性最初應設為 private,只有在真正有訪問需求時,才修改其權限,如果發現有很多程式碼都需要修改,那麼應該重新檢視系統架構。如果在 subclass 覆寫方法,那它的訪問級別不能低於 super class 的定義,當 subclass 覆寫方法的訪問性低於 super class,在編譯時就會錯誤,實作介面的方法皆為 public。
在 public class 中的 field 絕對不能是 public 的,因為這樣會對該 field 失去控制權,調用者是有能力修改它的內容,但有例外就是用 public static final 來表示常數,該 field 應為基本數值或是不可變的引用。結論,設計上應盡量的降低所有成員的的可訪問性。
// Thing 陣列內的元素是有機會被修改的
public static final Thing[] VALUES = { ... };

// 兩種修改方式,將陣列宣告為 private 後提供可訪問的方法
private static final Thing[] PRIVATE_VALUES = { ... };
public static final List<Thing> VALUES =
  Collections.unmodifiableList(Arrays.asList(PRIVATE_VALUES));

public static final Thing[] values() {
  return PRIVATE_VALUES.clone();
}
轉載請註明原文網址 https://cookieandcoketw.blogspot.com/2020/07/effective-java-15-class-accessibility.html

沒有留言:

張貼留言