簡體   English   中英

在java中創建對象的最佳實踐

[英]Best practice to creating Objects in java

我正在閱讀Joshua Bloch寫的Effective Java一書。 在第一章中,他說使用工廠而不是構造函數,並列出了這種方法的優缺點。 據我所知,缺點與對象構造沒有密切關系。

此外,Bloch說Java Bean的構造方式也有缺點。 資料來源: http//www.javapractices.com/topic/TopicAction.do? Id= 84

好的,所以使用構造函數不是很好,Java bean不是很好,工廠很好,所以你可以做一些緩存查找並避免創建額外的對象(取決於情況,有時你不想要緩存)。

如果我試圖避免構造函數和java bean,我應該怎么創建一個對象?

我錯過了一點嗎? 什么是最佳做法?

編輯:

class Foo{
   private Foo(){}

   public Foo Create(){
      return new Foo();
   }

}

使用構造函數,直到你開始感受到Bloch提到的缺點。 然后考慮工廠,依賴注入或其他方法是否更好。

將構造函數用於具有少量參數的簡單對象。 如果參數的數量增加,那么就開始考慮bloch建議的構建器或工廠。

大多數簡單案例,構造函數都能很好地完成工作。

我的經驗是,如果定義對象的屬性數量增長很多,我會回過頭來檢查設計並找出是否必須以更好的方式對屬性進行分組。 就像DININGTABLE可以分成n個腿+ 1個頂部木制部分。

如果對所有對象構造使用工廠模式,則看起來不太好。

  • 除非有充分的理由,否則永遠不要在你的類中使用類似setter的java bean *你會感謝我這樣說,因為這將使代碼的維護成為一場噩夢 - 你永遠不知道調用seters的人是誰以及如何調用對象的狀態。 對象應該通過構造函數盡可能多地構造,盡可能使它們成為不可變的,如果不是通過一種或兩種方法只通過幾種方式來更新對象的狀態。

這取決於場景。 正如您所提到的,如果涉及緩存,那么靜態工廠是更好的方式。 如果有很多狀態變量,那么使用Builder模式。

您可能有興趣熟悉依賴注入模式, Google Guice是實現它的最流行的框架之一。

好吧,我覺得那個人正在苦苦掙扎的是Inversion of Control模式:

http://en.wikipedia.org/wiki/Inversion_of_control

不要在這里做論文,我只是說在對象實例的這個狹窄的上下文中反轉控制是指對物體實例進行單獨服務處理的事實(和好處),而不是手動實例化那些對象。 實現這一目標的一種方法是工廠模式,根據你的說法,這個人正在描述。 另一個是使用一個為你做IOC的框架,比如Spring:

http://static.springsource.org/spring/docs/2.0.x/reference/beans.html

(真的離工廠模式不遠)

第三種選擇是創建自己的IOC機制,以某種方式處理對象實例化,這樣您就不必每次都明確地執行它。

這里的想法不是停止使用構造函數來創建實例,你總是使用它來獲取實例,這里的想法是WHEN以及你如何調用該構造函數:

  • 你在需要實例的類中直接調用它嗎?
  • 你有一個單獨的機制(如工廠)處理需要時獲取該實例(依賴),這樣你就不會自己明確地做

兩種方式都有優點。 通常情況下,單獨處理實例更好,而不是手動執行,因為它會導致更清晰,耦合度更低,代碼更易測試。

如果你遇到一個正在做數學的程序來計算一周中哪一天到處都是,你會怎么想? 您可能會認為“數學可以計算出它應該采用自己的方法中的哪一天,因此它可以只表達一次,只要代碼需要知道哪一天,就可以調用該方法本周是“。

構建一個對象與確定一周中的哪一天是完全沒有區別的。 在一個地方做它,使它成為一個方法,並從你需要一個新對象的地方調用該方法。

現在,在某些情況下,該方法本身可以是構造函數(構造函數實際上只是一種有趣的方法,對吧?)。 在其他方法中,該方法將調用構造函數,該構造函數不會在其他任何地方使用。 這取決於創建對象需要做多少工作,以及要隱藏要創建的對象的類多少(想象一下createDaysOfTheWeek工廠方法 - 它可以返回Collection<DayOfTheWeek> ,並隱藏這樣的事實:它是一個ArrayListLinkedHashSetEnumSet或其他)。 以工廠方法包裝結構可以為您提供更多封裝,但透明度更低。 制作好的代碼需要這兩種品質,但是像啤酒和餡餅一樣,你需要平衡它們。

始終在上下文中判斷建議。 構造函數是創建對象的標准方法,但它們並非完全沒有缺點。

例如,他談到了一個服務提供者框架 - 這只能在構造對象的工廠方法上實現。 但關鍵是你不要一直設計服務提供者框架。

他再次引用了Collection框架中使用實例控制類的示例。 如果將對象創建限制為簡單構造函數樣式,則無法執行此操作。 但同樣,日常代碼不需要采用實例控制的類。

他支持工廠方法還有其他一些案例 - 所有這些都是在某些使用環境下進行的。 在其他情況下,構造者可能就足夠了。

您可以使用Cinstructor創建對象,如使用new,如下所示:

Foo f=new Foo();

有一個名為singleton的概念。在這種情況下,您可以使用上面顯示的此類型,但是使create函數為static,否則用戶將如何調用函數create,如下所示:

class Foo{
   private Foo(){}

   public static Foo Create(){
      return new Foo();
   }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM