2011-04-05 92 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); 
     } 
}