何时使用构造函数以及何时使用getInstance()方法(静态工厂方法)?

zen*_*ngr 79 java

  1. 何时以及如何使用构造函数

    Foo bar = new Foo();
    
    Run Code Online (Sandbox Code Playgroud)
  2. 我们何时以及如何使用getInstance()(静态工厂方法)

    Foo bar = Foo.getInstance();
    
    Run Code Online (Sandbox Code Playgroud)

这两者有什么区别,我总是使用第一种方式,但何时使用第二种方式?

Pas*_*ent 91

每个人似乎都专注于单身,而我认为问题实际上是关于构造函数与静态工厂方法.

这实际上是第1项:考虑静态工厂方法而不是 Joshua Bloch 的 Effective Java 构造函数:

第1项:考虑静态工厂方法而不是构造函数

类允许客户端获取自身实例的常规方法是提供公共构造函数.还有另一种技术应该是每个程序员工具包的一部分.类可以提供公共 静态工厂方法,它只是一个返回类实例的静态方法.这是一个简单的例子Boolean(原始类型的盒装基元类 boolean).此方法将布尔基元值转换为 Boolean对象引用:

public static Boolean valueOf(boolean b) {
    return b ? Boolean.TRUE : Boolean.FALSE;
}
Run Code Online (Sandbox Code Playgroud)

请注意,静态工厂方法 与" 设计模式 "中的" 工厂方法" 模式不同 [Gamma95,p.107].此项中描述的静态工厂方法在设计模式中没有直接等效项.

类可以为其客户端提供静态工厂方法,而不是构造函数,或者除了构造函数之外.提供静态工厂方法而不是公共构造函数具有优点和缺点.

优点(引用本书):

  • 静态工厂方法的一个优点是,与构造函数不同,它们具有名称.
  • 静态工厂方法的第二个优点是,与构造函数不同,它们不需要在每次调用时创建新对象.
  • 静态工厂方法的第三个优点是,与构造函数不同,它们可以返回其返回类型的任何子类型的对象.
  • 静态工厂方法的第四个优点是它们减少了创建参数化类型实例的详细程度.

缺点(仍引用本书):

  • 仅提供静态工厂方法的主要缺点是没有公共或受保护构造函数的类不能被子类化.
  • 静态工厂方法的第二个缺点是它们不容易与其他静态方法区分开.

  • 最后一个可以稍微减轻.我倾向于有一个名为Factory的静态内部类和各种newInstance方法,以便在创建工厂方法时更清晰.它让我在过去的时间里拯救了我.:) (7认同)
  • +1,这也是我理解这个问题的方式. (3认同)

Chr*_* B. 8

你有两个问题:我什么时候应该调用一个getInstance()方法,什么时候应该创建一个?

如果你决定是否要调用一个getInstance()方法,这很容易.您只需阅读课程文档,了解何时应该调用它.例如,NumberFormat提供了一种构造一个getInstance()方法; 该getInstance()方法将为您提供本地化NumberFormat.对于Calendar,在另一方面,构造函数是受保护的.你必须打电话getInstance()来得到一个.

如果你决定是否要创建一个getInstance()方法,你需要决定你想要完成的任务.要么你希望人们调用你的构造函数(你正在创建一个单例工厂),或者你不介意(NumberFormat如上所述,他们为了方便调用者而初始化一些对象).


长话短说?不要担心getInstance()在自己的代码中创建方法.如果它们有用的时候出现,你就会知道.一般来说,如果你可以调用一个类的构造函数,你可能应该这样做,即使该类提供了一个getInstance()方法.


kro*_*ock 7

getInstance方法的用法:

但是大多数时候你的对象将是一个简单的POJO,并且使用公共构造函数是最实用和最明显的解决方案.

U1:来自另一个类的getInstance

要返回不同类的实例:

public class FooFactory {
    public static Foo getInstance() {
        return new Foo();
    }
}
Run Code Online (Sandbox Code Playgroud)

NumberFormat.getInstance方法执行此操作,因为它们实际返回实例DecimalFormat.

U2:单身人士问题

单例模式限制了面向对象编程的许多好处.单身人士通常拥有私人建筑师,因此你无法扩展他们.由于您将通过其getInstance方法访问它而不引用任何接口,因此您将无法将其交换为另一个实现.


jde*_*aan 6

如果你可以使用它们,那么它听起来像一个执行不佳的单例模式.

如果您打算在系统中只有一个类的单个实例,那么请使用第二个选项,然后将构造函数设为私有.

使用第一个允许构建类的多个对象.

但是不要给你的班级两种可能性.

注意不要过度使用单例,只有在系统中只存在一个实例时才使用它们,否则你将限制在其他项目中重复使用你的类的可能性.能够从项目中的任何地方调用getInstance听起来很有趣但是不清楚谁实际拥有该实例:nobody和/或all.如果你在项目中有很多单身人士,你可以打赌系统设计很差(通常).应谨慎使用单身人士,与全局变量相同的建议相同.

  • ------>"注意不要过度使用单身人士"<------ (4认同)