【问题标题】:Java Best Practice new vs .create() [duplicate]Java最佳实践新与.create()[重复]
【发布时间】:2013-06-23 16:26:32
【问题描述】:

嗯,我有一个非常概念性的问题。很多东西看起来像织物,我不确定它的好处在哪里。 举例

public class MyObject {
public MyObject() {

}
public static MyObject create() {
    return new MyObject();
}

public void doSomething(){
    // some code...
};

}

在我看来,唯一的好处是对代码的出价更少。在我看来,对性能没有影响。还有其他好处吗?

MyObject myobject = new MyObject();

MyObjecct myobject = MyObject.create();

谢谢

【问题讨论】:

标签: java conceptual


【解决方案1】:

您是正确的,没有显着的性能差异;而使用这种形式的原因主要是代码的可读性。

一般来说,如果您使用静态创建函数,您会声明构造函数为私有,从而确保您的用户只能使用静态函数创建对象

总的来说,我认为静态创建不会对代码增加太多,对于普通的日常物品来说,新的可能更清晰、更直接。

不过在某些情况下我认为静态构造函数是有用的:

  1. 对于大型复杂对象的构造,尤其是在初始化过程中涉及大量复杂性的对象 - 简单的构造函数通常会误导库用户,让他们认为构造任务既快速又简单。
  2. 如果您有多个参数不明确的构造函数,您可以使用静态函数名称使其更具可读性,例如您可能有 createFromFile(String FileName) 和 createFromJSONEncoding(String Data)
  3. 您想控制是否实际创建了一个新对象 - 例如,如果这是一个只读资源,您可能会保留一个已打开资源的缓冲区,并且如果库用户两次请求相同的资源,您可以简单地给出它们是已经缓存的副本(而不是制作新的副本)

【讨论】:

    【解决方案2】:

    Joshua Bloch 在 Effective Java,第 2 章,第 1 项:考虑静态工厂方法而不是构造函数中解决了这个问题;以下是一些亮点:

    • “静态工厂方法的一个优点是,与构造函数不同,它们 有名字。”——你不能有两个不同的构造函数接受int 参数,但你可以有两个静态工厂方法,称为createWithAge(int age)createWithHeight(int height)
    • “静态工厂方法的第二个优点是,与构造函数不同, 他们不需要在每次调用时都创建一个新对象。”
    • “静态工厂方法的第三个优点是,与构造函数不同, 它们可以返回其返回类型的任何子类型的对象。”

    如您所见,关注点与性能几乎没有关系(除了重用缓存实例),而主要与面向对象的设计有关。

    免责声明:糟糕,我刚刚看到相同的答案(解释得更好)已针对不同的问题发布:https://stackoverflow.com/a/3169644/262683。我的坏...

    【讨论】:

      【解决方案3】:

      这个问题没有答案。

      事实上,这两种模式都是构造适用于特定情况的对象的合法方式。

      静态工厂方法在实例控制非常重要的情况下很重要,例如在维护对象缓存或池的系统中。

      new 运算符因其简单而易于使用,并且对于为继承而设计的类相当重要。

      您在问什么是最佳实践。答案是,最佳做法取决于您的目标,并且对于此类问题,最佳做法是明智地利用可用工具来实现可扩展和可维护的解决方案。

      我建议关闭这个问题。

      【讨论】:

      • -1 你暗示有一个答案'最佳实践取决于你的目标',拒绝解释这个答案 - 然后告诉提问者这是一个糟糕的问题。如果你有这种感觉,如果你没有代表投票结束,你应该投票否决这个问题。
      • @Elemental:好的,所以......“静态工厂方法的哪一部分对实例控制很重要”......和......“新的适合为继承设计的类”不听起来像是对你的解释?
      【解决方案4】:

      我看到你可能需要使用create的情况:

      您必须控制类的每个实例的创建。例如,您计算创建的对象数量或以某种方式链接它们,以及实例数量是否达到您期望的最大抛出异常。

      还有factory pattern 可能会很有趣。

      如果您不确定,只需通过new 创建即可

      如果您选择使用create,您可能希望将您的构造函数设为私有

      【讨论】:

      • 构造函数也可以抛出异常。
      • 当然,我的意思是它会检查一些约束并抛出异常
      • 这与你在构造函数中可以做的有什么不同?
      • 你可以做任何你想做的事,它只是让代码更清晰,更易读
      【解决方案5】:

      这是一个(简单的)Factory Pattern。请检查 Wikipedia 条目的适用性部分以了解其使用位置。

      【讨论】:

        【解决方案6】:

        现在,当您不希望任何其他类创建您的类对象时,您可以将类构造函数设为私有:

        private MyObject()
        

        现在任何想要创建你的类对象的类都必须这样做:

        MyObjecct myobject = MyObject.create();
        

        因为现在在其他一些类MyObject myobject = new MyObject(); 中这样做会导致编译器错误。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-11-11
          • 1970-01-01
          • 2020-03-22
          • 1970-01-01
          • 2019-04-03
          • 2013-07-03
          • 2011-02-11
          • 2011-01-28
          相关资源
          最近更新 更多