靜態(tài)工廠方法雞肋嗎?

對比靜態(tài)工廠

靜態(tài)工廠方法很容易讓人想到設計模式的靜態(tài)工廠,也叫簡單工廠,作者說兩者不同,我認為這兩者僅是從概念上來講有區(qū)別,從技術(shù)的角度來講沒有區(qū)別

簡單來說,其區(qū)別體現(xiàn)在:靜態(tài)工廠方法所在的類的意義是具體的,并且這個方法只創(chuàng)造與這個方法所在類直接相關(guān)的對象。而靜態(tài)工廠的概念與靜態(tài)工廠方法并不等同,靜態(tài)工廠是更寬泛的概念,其實現(xiàn)包含了靜態(tài)工廠方法,靜態(tài)工廠里的靜態(tài)工廠方法生產(chǎn)的不是工廠本身,是工廠里的產(chǎn)品,與其所在的類間接關(guān)聯(lián)。

技術(shù)上沒有區(qū)別,這兩者的代碼結(jié)構(gòu)是一致的,且靜態(tài)工廠方法里可以使用靜態(tài)工廠來獲得結(jié)果,靜態(tài)工廠也可以使用產(chǎn)品的靜態(tài)工廠方法。靜態(tài)工廠方法的優(yōu)點靜態(tài)工廠也都可以有。

對比構(gòu)造方法

  • 優(yōu)勢方面

靜態(tài)工廠方法與構(gòu)造方法相比,不同的地方在于:

  1. 靜態(tài)工廠方法可以有自定義方法名,而構(gòu)造方法必須等同于類名
  2. 靜態(tài)工廠方法可以自定義返回值,而構(gòu)造方法可以間接等同于只能返回自己的實例

縱觀作者總結(jié)的5大好處:

  1. 可讀性強,因為可以任意命名,還可以用于實現(xiàn)多構(gòu)造方法
  2. 構(gòu)造方法只要調(diào)用就會產(chǎn)生一個對象,但靜態(tài)工廠方法返回的可以不是新創(chuàng)建的
  3. 可以返回當前類的任意子類對象,常用于接口
  4. 每次調(diào)用都可以根據(jù)參數(shù)返回不同的類,EnumSet的例子,會根據(jù)需要的大小返回不同的EnumSet
  5. 返回的對象所屬的類,在寫代碼的時候可以不存在。

實際就是這兩個方面,靈活的方法名和靈活的返回值帶來的好處。

靜態(tài)工廠方法的第一類好處是說有意義的方法名提高了代碼可讀性,這不是靜態(tài)工廠方法獨有的,是編程世界里所有的普通方法都有的好處。這啟發(fā)我們在寫代碼的過程中無論你是面向過程也好,面向?qū)ο笠埠?,面向接口,還是面向其它XXX也好,多寫方法,多取有意義的方法名,這是提升代碼可讀性非常有效的方式,比很多開發(fā)只知道寫注釋有用多了。

第二類關(guān)于返回值的好處說了很多條,都很有用,觀念上具有指導作用,但在現(xiàn)在的Java世界,一定有必要按照這種方法去實踐嗎?可能很多情況下都沒有必要了。

比如第二點,其實主要應用就是一些緩存啊,單例之類的場景。就拿單例來說,使用靜態(tài)工廠方法實現(xiàn)懶漢式單例,你還需要解決線程安全的問題,解決代碼編譯重排的問題,解決這個問題復雜嗎?不復雜,有必要嗎?可以沒必要,使用Spring Bean,完全可以拋棄這么原始的做法。

后面幾點好處比較常用的場景基本都是在使用接口的情況下,靜態(tài)工廠方法可以返回接口不同的實現(xiàn),那有了Spring這么強大的IoC框架,靜態(tài)工廠方法作為學習,理解思路可以,實現(xiàn)業(yè)務的時候其實有更好的工具。

特別提一下第5點,這個著實理解了很久,最后我覺得作者可能是從編譯class的角度在說,就是你這個方法可以返回一個編譯時不存在,只出現(xiàn)在運行時的實現(xiàn)類。從這個角度出發(fā),我想到兩類場景,一類是通過反射在運行時獲得真正的對象。典型的應用比如Class.forName。還有一類場景是使用動態(tài)配置的場景,比如我創(chuàng)造一個map,在運行里會加載DB里的動態(tài)配置,靜態(tài)工廠方法可以在寫代碼的時候不需要這個具體的配置類存在,再扯遠一些比如枚舉,其實返回的枚舉類也是可以不存在的,這些場景不一定典型,但我覺得也符合這個好處。

總結(jié)一下,靜態(tài)工廠方法有些場景下可以提升代碼可讀性,可以使用,至于單例或者解耦的場景,我們有更強大的工具可以使用,使用靜態(tài)工廠方法比較原始,會有很多問題需要去解決。不過,如果用不了強大的工具,那也只能回歸原始。帶來的啟發(fā)是,多寫方法,多用接口。

  • 劣勢方面

靜態(tài)工廠方法當然也有缺點:

  1. 使用靜態(tài)工廠方法通常需要把構(gòu)造方法私有化,因此不能被子類化。
  2. 靜態(tài)工廠方法比較隱晦,不易被發(fā)現(xiàn),一般可以采用約定的名稱來命名使其容易被發(fā)現(xiàn)。

都是小問題。在不容易被發(fā)現(xiàn)這點后提了一些靜態(tài)工廠方法的約定,我倒覺得有點意思。像from,of,instance這些詞很有意義嗎?我覺得并不,那豈不是不符合靜態(tài)工廠方法可以增加可讀性的特點?對,胡亂使用的情況下我覺得還不如回歸到構(gòu)造方法。但注意,作者實際上補充了一大堆這些命名背后的含義,也就是說這些命名需要基于約定。達成約定后這些命名含義就具體了。然而我覺得這件事不簡單,你比如說Java官方的Optional.of(),并不符合作者要求的of用于聚合的情景。

那到底還用不用,是不是雞肋呢?我支持用,原因是這樣寫出來的代碼更美觀,這可能是第6個優(yōu)點:賞心悅目。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容