1. 程式人生 > 其它 >重構:用靜態工廠方法代替構造方法

重構:用靜態工廠方法代替構造方法

技術標籤:程式碼重構

對於類而言,為了讓客戶端獲取它自身的一個例項,最傳統的方法就是提供構造方法。除此之外,我們今天將介紹的靜態工廠方法也是被用得很廣泛的一種方式。比如Boolean原始碼中將boolean基本型別值轉換成一個Boolean物件引用:

public static Boolean valueOf(boolean b) {
    return (b ? TRUE : FALSE);
}

如果不通過公有的構造方法,或者說除了公有的構造方法之外,類還可以給它的客戶端提供靜態工廠方法。提供靜態工廠方法而不是公有的構造方法,這樣做既有優勢,也有劣勢。

1. 優勢

(1)第一大優勢在於,靜態工廠方法是有名稱的。如果構造方法的引數本身沒有確切地描述正在建立的物件,那麼具有適當名稱的靜態工廠會更容易使用,產生的客戶端程式碼也更易於閱讀。

(2)第二大優勢在於,不必在每次呼叫它們的時候都建立一個新的物件。這使得不可變類可以使用預先建立好的物件,或者將構建好的例項快取起來,進行重複利用,從而避免建立不必要的重複物件。上訴Boolean.valueOf(boolean b)方法就是如此,它從來不建立物件,而是返回快取中的物件。

(3)第三大優勢在於,它們可以返回原返回型別的任何子類物件。比如Arrays.asList()方法返回的就是List介面的一個子類物件。

2. 劣勢

(1)第一大劣勢在於,程式設計師很難發現它們。在API文件中,它們沒有像構造方法那樣在API文件中明確標識出來,因此,對於提供了靜態工廠方法而不是構造方法的類來說,要想查明如何例項化一個物件是非常困難的。這一點需要我們通過在類或者介面註釋中關注靜態工廠,並遵守標準的命名習慣來彌補這一劣勢。下面是靜態工廠方法的一些慣用名稱:

  • from:型別轉換方法,它只有單個引數,返回該型別的一個物件。比如:Date date = Date.from(instant)
  • of:聚合方法,帶有多個引數,返回該型別的一個物件,把它們合併起來。比如:Set<Rank> faceCards = EnumSet.of(JACK, QUEEN, KING)
  • valueOf:比如:BigDecimal.valueOf(long val)
  • instance或者getInstance:大部分見於單例類。
  • create或者newInstance:和instancegetInstance一樣,但create或者newInstance能夠確保每次呼叫都返回一個新的例項物件。
  • get<Type>:像getInstance一樣,但是在工廠方法處於不同的類中的時候使用。比如:FileStore fs = Files.getFileStore(path)
  • new<Type>:像newInstance一樣,但是在工廠方法處於不同的類中的時候使用。比如:BufferedReader br = Files.newBufferedReader(path)
  • typeget<Type>newType的簡版,比如:List<Complaint> litany = Collections.list(legacyLitany)
——End——
更多精彩分享,可掃碼關注微信公眾號哦。

在這裡插入圖片描述