2011-04-05 180 views
0

在這個網站上面說一個新的對象心不是被每次創建,從而導致效率的,但我可以看到一個對象被靜態方法每次創建..靜態工廠方法問題!

不需要在每次調用時創建一個新對象 - 如果需要,可以將對象緩存並重新使用 。

http://www.javapractices.com/topic/TopicAction.do?Id=21

爲什麼是靜態的工廠方法是如此有效?

沒有寫這樣的東西:Object obj = new Object與我做的一樣Object obj = Someclass.GetObj();

class Someclass 
{ 
    public static Object GetObj() 
    { 
    return new Object 
    } 
} 

有緩存,而是一個新的對象被創建兩種方式...

回答

1

它們更靈活 - 例如,如果新對象的輸入參數無效,則可以返回null或一些null對象實現(即實例,它什麼都不做,但不會因NullPointerException而破壞您的代碼),或者正如其他人之前提到的那樣,您可以緩存創建的實例。使用工廠方法比構造函數還有另一個好處 - 如果有多個具有許多可選參數的構造函數,您可以隨意命名它們,這可以更易讀。

編輯:如果你想使用只有一個實例,你可以使用這個簡單的工廠:

class Someclass{ 
    private static Object o=new Object(); 

    public static Object getObj(){ 
    return o; 
    } 
} 
1

當您使用new Object(),一個新的對象已經被創建。

如果您使用靜態工廠,則可以選擇創建一個新對象,或者可以重用現有對象。

一個簡單的例子是使用Integer.valueOf(int)而不是new Integer(int)。靜態工廠有一個小整數緩存,可以節省大量整數的創建。對於一些用例,這可以是所有使用的整數。後面的例子總是會創建一個相對低效的新對象。

+0

我編輯quesion – 2011-04-05 12:36:17

+0

下載一些數據,如果你有一個工廠,永遠只是調用構造函數,這將是一樣的剛調用構造函數。如果它做了一些不同的事情,它只會表現不同。 – 2011-04-05 13:14:26

3

對象可以被緩存和重用。他們並不總是。還有一些其他優勢,如:

  • 更好的命名方法
  • 的返回子類

有有效的Java的一個項目,所以,儘管閱讀。無論如何,這本書是一本必讀書。

更新:正如我所說的,對象可以緩存。但這取決於實施。你展示的那個不會緩存它們。彼得展示的那個緩存它們。你有這個選擇。用一個構造函數 - 你不知道。

+0

我有這本書,我現在正在讀它..仍然不明白他們說的一點,一個對象不必實例化 – 2011-04-05 12:43:00

0

這個想法是,你使用它們作爲一種策略。如果稍後想要實現緩存,則只需更改該方法並將其添加到那裏即可。比較這與「全新的Bla()」分散在代碼中,並試圖爲Bla類實現緩存。

由於該方法是靜態的,通常只有幾行代碼,這意味着它可以在編譯時解析,甚至內聯。

因此,根本沒有使用「新Bla()」而不是工廠方法的優勢。

1

您介紹的鏈接提供了一個工廠模式非常不同的解釋。通常,工廠模式用於獲取實現相同接口但爲同一合同提供不同行爲的類的實例。它允許我們在運行時選擇不同的實現。看看這裏的例子:一般不用於緩存對象

http://www.allapplabs.com/java_design_patterns/factory_pattern.htm

工廠模式。單例模式被定義爲確保只創建一個對象實例。

0

在某些情況下使用工廠,您可以使您的代碼更靈活,更快,也更易讀。

例如,想象一下,你必須寫類從URL

public class WavAudio { 
     private byte[] raw; 
     private static HashMap<String,WavAudio> cache; 
     private WavAudio(byte[] raw){ 
      this.raw=raw; 
     } 
     public static loadFromUrl(String someUrl){ 
      //If data has been loaded previously we don't have to do this more (faster..) 
      if (cache.containsKey(someUrl)) 
       return cache.get(someUrl); 
      //Else we'll load data (that would take some time) 
      InputStream ires=(new URL(someUrl)).openStream();  
      ByteArrayOutputStream baos=new ByteArrayOutputStream(); 
      byte[] raw = new byte[4096];   
      int nBytesRead; 
      while ((nBytesRead = ires.read(raw, 0, raw.length))>0) 
      baos.write(raw, 0, raw); 
      byte[] downloaded=baos.toByteArray(); 
      WavAudio curr=new WavAudio(raw); 
      cache.put(someUrl,raw); 
      return raw; 
     }  

     public static void main(String[] args){ 
      WavAudio wav=WavAudio.loadFromUrl("http://someUrl_1"); 
      SomePlayer.play(wav); //the first melody is playing 
      WavAudio wav=WavAudio.loadFromUrl("http://someUrl_2"); 
      SomePlayer.play(wav); //the second melody is playing 
      //won't be downloaded twice 
      WavAudio wav=WavAudio.loadFromUrl("http://someUrl_1"); 
      SomePlayer.play(wav); 
     } 
}