2020/06/23

[筆記] Effective Java #3 用 private constructor 或者 enum 強化 singleton 屬性

Effective Java #3 用 private constructor 或者 enum 強化 singleton 屬性
一般實作 singleton 的方式有兩種,皆需使用 private constructor,第一種是在 class 定義一 public field,優點為清楚的說明該 class 是 singleton 狀態,另外對開發者來說,它簡單明瞭。
public class StaffPricingModel extends PricingModel {
    public static final PricingModel INSTANCE = new StaffPricingModel();
    private StaffPricingModel() { }
}
第二種是 static factory,開發者經由 getInstance() 來拿到 PricingModel 實體,優點為彈性較高,如果想要變成 non-singleton 時,只需要修改 getInstance() 即可,開發者不會受影響,同時也可以成為一個 Supplier<PricingModel>
public class StaffPricingModel extends PricingModel {
    private static final PricingModel INSTANCE = new StaffPricingModel();
    public static PricingModel getInstance() {
        return INSTANCE;
    }
    private StaffPricingModel() { }
}
如果當一個 singleton class 要支援序列化時,除了要實作 Serializable 外,還需要將其內部的實體宣告為 transient,並提供 readResolve(),否則每次在反序列化時,都會產生新的實體,該 class 也就不會是 singleton,這部分後面的章節會再深入討論 [#89]。
Java transient
https://dotblogs.com.tw/grayyin/2016/07/05/145920
Singleton pattern serialization
https://stackoverflow.com/questions/3930181/how-to-deal-with-singleton-along-with-serialization
最後一種方法為用 enum 來實作 singleton,馬上解決上述的序列化問題,雖然這種方式並不常採用,但也是實作 singleton 的一種方式。如果 singleton 必須去繼承其它 class 或實作 interface,就不建議採用這種作法。
public enum StaffPricingModel {
    INSTANCE;
    public void getDiscount() { }
}
轉載請註明原文網址 https://cookieandcoketw.blogspot.com/2020/06/effective-java-3-private-constructor.html

沒有留言:

張貼留言