简体   繁体   English

静态工厂方法的问题!

[英]static factory method question!

in this site it says that a new object isnt being created each time , which leads to efficiency, but by what i can see an object is being created each time in the static method.. 在这个站点上,它说每次都不会创建一个新的对象,这会提高效率,但是通过我可以看到,每次使用静态方法创建的对象都是。

do not need to create a new object upon each invocation - objects can be cached and reused, if necessary. 不需要在每次调用时都创建一个新对象-如有必要,可以缓存和重用对象。

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

so why are the static factory methods are so efficient? 那么为什么静态工厂方法如此高效?

isnt writing something like this : Object obj=new Object is same as if i did Object obj=Someclass.GetObj(); 不是写这样的东西:Object obj = new Object就像我做了Object obj = Someclass.GetObj();一样。

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

There is caching, but a new object is created either way... 有缓存,但是无论哪种方式都会创建一个新对象...

Objects can be cached and reused. 可以缓存和重用对象。 They aren't always. 他们并不总是如此。 There are a number of other advantages, like: 还有许多其他优点,例如:

  • better naming of the method 更好地命名方法
  • returning subclasses 返回子类

There is an item in Effective Java for that, so go ahead and read it. 有效Java中有一个用于该目的的项目,因此请继续阅读。 The book is a must-read anyway. 无论如何,这本书是必读的。

Update: as I said, object can be cached. 更新:正如我所说,对象可以被缓存。 But it depends on the implementation. 但这取决于实现方式。 The one you show does not cache them. 您显示的那个不会缓存它们。 The one shown by Peter caches them. Peter展示的那个缓存了它们。 You have that option. 你有那个选择。 With a constructor - you don't. 使用构造函数-您不需要。

When you use new Object() , a new Object has to be created. 当您使用new Object() ,必须创建一个新的Object。

If you use a static factory, it can optionally create a new object, or it can reuse an existing one. 如果使用静态工厂,则可以选择创建一个新对象,也可以重用现有对象。

A simple example is using Integer.valueOf(int) instead of new Integer(int) . 一个简单的示例是使用Integer.valueOf(int)而不是new Integer(int) The static factory has a cache of small integers and can save to the creation of a significant portion of integers. 静态工厂具有一个小整数的缓存,可以保存大部分的整数。 For some use cases this can be all the integers used. 对于某些用例,这可以是所有使用的整数。 The later case will always create a new object which is relatively inefficient. 后一种情况将始终创建效率相对较低的新对象。

They are more flexible - for example if the input parameters for new object are not valid, you can return null or some null object implementation (=instance, which does nothing, but will not break your code by NullPointerException), or, as previously mentioned by others, you can cache created instances. 它们更加灵活-例如,如果新对象的输入参数无效,则可以返回null或某些null对象实现(= instance,不执行任何操作,但不会因NullPointerException破坏代码),或者如前所述其他人可以缓存创建的实例。 There is another benefit from using factory methods over constructors - you can name them whatever you like, which can be more readable, if there are multiple constructors with lots of optional parameters. 使用工厂方法而不是构造函数还有另一个好处-如果有多个带有很多可选参数的构造函数,则可以随意命名它们,这样可读性更好。

EDIT: if you want to use only one instance, you can use this simple factory: 编辑:如果只想使用一个实例,则可以使用这个简单的工厂:

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

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

The link you presented provides very different explanation of a Factory Pattern. 您提供的链接提供了关于工厂模式的非常不同的解释。 Generally factory pattern is used to obtain instances of classes whcih implement same interface but provide different behavior for the same contract. 通常,工厂模式用于获取实现相同接口但为同一协定提供不同行为的类的实例。 It allows us to choose different implementation at run time. 它允许我们在运行时选择不同的实现。 Check out the example here: 在此处查看示例:

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

Factory pattern is not generally used for caching objects. 工厂模式通常不用于缓存对象。 Singleton pattern is defined to ensure only one instance of the object is created. 定义单例模式以确保仅创建对象的一个​​实例。

The idea is that you use them as a strategy. 想法是您将它们用作策略。 If later you want to implement caching, you just change that method and add it in there. 如果以后要实现缓存,则只需更改该方法并将其添加到其中即可。 Compare this with having "new Bla()" scattered all over the code, and trying to implement caching for the Bla class. 与此相比,将“ new Bla()”散布在代码中,并尝试为Bla类实现缓存。

Since the method is static, and usually just a few lines of code, it means it can be resolved at compile time, and even inlined. 由于该方法是静态的,通常只有几行代码,因此它可以在编译时甚至内联的方式进行解析。

Thus there is no advantage of using "new Bla()" instead of factory methods at all. 因此,根本没有使用“ new Bla()”代替工厂方法的优势。

Using factory in some situations you could make your code more flexible, faster and also better readable. 在某些情况下使用工厂,可以使代码更灵活,更快并且可读性更好。

For example, imagine, you have to write class which download some data from url 例如,假设您必须编写一个类,该类将从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);
      }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM