什么是“静态工厂”方法?


当前回答

当您希望确保只有一个实例将返回要使用的具体类时,静态工厂方法很好。

例如,在一个数据库连接类中,您可能希望只有一个类创建数据库连接,因此如果您决定从Mysql切换到Oracle,您只需更改一个类中的逻辑,而应用程序的其余部分将使用新的连接。

如果您希望实现数据库池,那么也可以在不影响应用程序其余部分的情况下完成。

它保护应用程序的其余部分不受您可能对工厂所做的更改的影响,这就是目的。

它是静态的原因是,如果你想跟踪一些有限的资源(套接字连接或文件句柄的数量),那么这个类可以跟踪已经传递和返回了多少,这样你就不会耗尽有限的资源。

其他回答

工厂方法:将对象的实例化抽象出来的方法。一般来说,当你知道你需要一个实现接口的类的新实例,但你不知道实现类时,工厂是有用的。

这在处理相关类的层次结构时非常有用,GUI工具包就是一个很好的例子。您可以简单地对每个小部件的具体实现的构造函数进行硬编码调用,但是如果您想要将一个工具包交换为另一个工具包,那么您将有很多地方需要更改。通过使用工厂,您可以减少需要更改的代码数量。

One of the advantages of the static factory methods with private constructor(object creation must have been restricted for external classes to ensure instances are not created externally) is that you can create instance-controlled classes. And instance-controlled classes guarantee that no two equal distinct instances exist(a.equals(b) if and only if a==b) during your program is running that means you can check equality of objects with == operator instead of equals method, according to Effective java.

The ability of static factory methods to return the same object from repeated invocations allows classes to maintain strict control over what instances exist at any time. Classes that do this are said to be instance-controlled. There are several reasons to write instance-controlled classes. Instance control allows a class to guarantee that it is a singleton (Item 3) or noninstantiable (Item 4). Also, it allows an immutable class (Item 15) to make the guarantee that no two equal instances exist: a.equals(b) if and only if a==b. If a class makes this guarantee, then its clients can use the == operator instead of the equals(Object) method, which may result in improved performance. Enum types (Item 30) provide this guarantee.

摘自Effective Java, Joshua Bloch(第1项,第6页)

可读性可以通过静态工厂方法来提高:

比较

public class Foo{
  public Foo(boolean withBar){
    //...
  }
}

//...

// What exactly does this mean?
Foo foo = new Foo(true);
// You have to lookup the documentation to be sure.
// Even if you remember that the boolean has something to do with a Bar
// you might not remember whether it specified withBar or withoutBar.

to

public class Foo{
  public static Foo createWithBar(){
    //...
  }

  public static Foo createWithoutBar(){
    //...
  }
}

// ...

// This is much easier to read!
Foo foo = Foo.createWithBar();

如果类的构造函数是私有的,那么就不能从类的外部为类创建对象。

class Test{
 int x, y;
 private Test(){
  .......
  .......
  }
}

我们不能从上面的类的外部创建一个对象。所以你不能从类外访问x y。那么这门课有什么用呢? 下面是答案:FACTORY方法。 在上面的类中添加下面的方法

public static Test getObject(){
  return new Test();
}

现在你可以在这个类的外部创建一个对象。就像……

Test t = Test.getObject();

因此,通过执行类的私有构造函数返回类对象的静态方法称为FACTORY方法。

注意!“静态工厂方法与工厂方法模式不同”(c) Effective Java, Joshua Bloch。

工厂方法:定义一个用于创建对象的接口,但是让实现该接口的类来决定实例化哪个类。Factory方法允许类延迟实例化到子类“(c) GoF”。

静态工厂方法只是一个返回类实例的静态方法。(c)有效的Java,约书亚·布洛赫。通常这个方法在一个特定的类中。

的区别:

The key idea of static factory method is to gain control over object creation and delegate it from constructor to static method. The decision of object to be created is like in Abstract Factory made outside the method (in common case, but not always). While the key (!) idea of Factory Method is to delegate decision of what instance of class to create inside Factory Method. E.g. classic Singleton implementation is a special case of static factory method. Example of commonly used static factory methods:

返回对象的值 getInstance newInstance