Effective Java Item 1 note

consider static factory methods instead of constructors

Arwii
mycodingjourney
3 min readApr 14, 2018

--

如果要寫一個class然後用constructor去實例化它之前,可以考慮看看用static factory method的方式去實現這個class的實例化(跟factory method沒有關係).這種方法跟constructor相比有幾個好處

  1. 有名稱可以明確表達出產生的物件是什麼,也就是說比較好讀啦,例如書上的例子說BigInteger.probablePrimwe應該就可以看得出是產生一個可能是質數的大數,再者,當你遇到有兩個constructor以上的時候,也可以用這個方式去明確指出你在哪種情況要用哪個method去產生適合的物件,例如android的widget類別中,有很多的layout class(LinearLayout…等等)跟View class(Button…等等)的constructor都是底下圖片這種模樣

雖然每個constructor對應到的參數都很一致,第一個都是context,然後attribute set等等,但好像可以想想看這樣的寫法適不適合被static factory method所取代.這邊提到這個例子只是當每次在寫動態layout要new一些view的物件出來的時候,會想一下要用哪個constructor.

2. static factory method可以控制不必每次invoke的時候都要new一個新的class,這個優點會顯現在當你經常要求創建相同的object,然後該object建立的成本很高的時候.其次,可以”控制”這個要被建立出來的物件是個singleton或者是不可實例化的物件.

3. 可以將要返回的type抽象化,就可以決定你要返回的物件是什麼,這樣在application版本升級的時候也可以增加可維護性,盡量讓抽象對使用的人

4. 可以讓code變簡潔
書本上的例子是
Map<String, List<String>> m = new HashMap<String, List<String>>();
如果Java的HashMap有提供
Public static <K,V> HashMap<K,V> newInstance() {
return new HashMap<K,V>();
}
上面那段code就可以簡化成
Map<String, List<String>> m = HashMap.newInstance();

那static factory method的缺點有

  1. 如果該class只提供static factory method給class的實例化使用的話(constructor變成private了),就會沒辦法讓其他class去繼承他了,不過換個角度想也符合多用合成少用繼承這個原則
  2. 跟其他的static method沒有太大的區別,不能像constructor在文件中被明確的標示出來,不過現在java也沒有這個功能,所以目前只能用規範好的命名格式來彌補這項缺點。
    例如:
    getInstance, newInstance就可以區分要怎麼產生這個instance出來.

--

--

Arwii
mycodingjourney

Try not to become a man of success, but rather try to become a man of value — A. Einstein