2

类允许客户端获取实例的正常方式是提供公共构造函数。另一种方法是提供一个公共静态工厂方法,它只是一个返回类实例的静态方法。使用静态工厂方法有什么优缺点?

4

5 回答 5

11

《Effective Java》一书中的这一章很好地解释了这一点:考虑静态工厂而不是构造函数。它以您能理解的最佳方式解释了它们的所有优点和缺点。

只是引用书中的优点和缺点:

优点

  • 静态工厂方法的一个优点是,与构造函数不同,它们有名称。
  • 静态工厂方法的第二个优点是,与构造函数不同,它们不需要在每次调用时都创建一个新对象。
  • 静态工厂方法的第三个优点是,与构造函数不同,它们可以返回其返回类型的任何子类型的对象。
  • 静态工厂方法的第四个优点是它们减少了创建参数化类型实例的冗长性(在 Java 7 中可以忽略这一点)

缺点

  • 只提供静态工厂方法的主要缺点是没有公共或受保护构造函数的类不能被子类化

  • 静态工厂方法的第二个缺点是它们不容易与其他静态方法区分开来。

您可以在我提供的链接中更详细地研究它们。

于 2012-10-24T10:00:20.840 回答
2

唯一的缺点是要编写更多代码,但它仍然存在,因此拥有工厂至少需要一些好处。

工厂不需要总是返回一个新对象,这是一个优势。

工厂可以实例化它想要的任何子类,那是另一个。

在我的项目中,我经常添加工厂只是为了让我的客户端代码看起来更好。如果您对工厂方法使用静态导入,则调用看起来比new表达式更好,尤其是在类名不是特别简洁的情况下,这种情况经常发生。

于 2012-10-24T10:00:52.927 回答
1

优点: - 静态工厂方法的一个优点是,与构造函数不同,它们有名称。- 静态工厂方法的第二个优点是,与构造函数不同,它们不需要在每次调用时都创建一个新对象。- 他们可以返回其返回类型的任何子类型的对象。缺点: - 静态工厂方法的主要缺点是没有公共或受保护构造函数的类不能被子类化。- 它们不容易与其他静态方法区分开来。

于 2012-10-24T10:02:21.247 回答
0

我会对问题的原作者说静态工厂方法是一种工具。像所有工具一样,它们具有最适合的用途、尚可通过的其他用途以及难以适应的其他用途。举一个现实世界的例子,锤子很擅长打钉子,足以用去钉子的一端顶开一个密封的板条箱(撬棍仍然会好得多),但对于刨平粗糙的表面却无用。

工厂方法是指一组创建设计模式中的一个,即创建对象的范例。在诸如“Builder”和“Prototype”之类的创建设计模式中,不仅不鼓励使用 new 操作符来创建对象,而且认为它对整体设计目标有害。人们谈论的创造设计模式是……

  1. 工厂方法
  2. 抽象工厂方法
  3. 单例模式
  4. 建造者
  5. 原型

一般来说,工厂方法用于根据用户或设计者提供给方法的数据,从一组相关的子类中创建一个对象。更具体地说,静态工厂方法使您可以控制对象的创建,即使每次返回的对象都相同。例如,当创建对象的过程在时间和资源方面非常昂贵时,这可能非常重要。在这种情况下,使用 new 运算符创建对象可能会导致严重的性能损失。

一种解决方案可能是维护一个可重用的对象池。通过使用静态工厂方法,应用程序设计者可以提供逻辑来返回一个可用的免费现有对象。这将节省构建新对象的潜在高成本。这正是提供“连接池”的连接管理器对网络数据库连接所做的事情。不是在每次客户端发出请求时都建立一个新的数据库连接,而是从现有对象池中分配连接对象(如果可用的话)。这是使用新运算符实际上会损害应用程序性能并破坏软件工程师的设计目标的情况的示例。

考虑使用工厂方法而不是 new 运算符来创建对象的好时机是:

  • 将创建的对象属于可以根据提供的数据创建的几个可能的对象子类之一。
  • 有充分的理由对对象创建过程进行比在构造函数中更多的控制,例如。Singleton 设计模式需要静态工厂方法。

考虑使用工厂方法的最佳时机是:

  • 简单、轻量级的对象

这一切都是关于枚举软件设计问题,然后决定哪些工具最适合解决它。静态工厂方法对某些事情有好处,但对其他事情不太好……就像任何工具一样。

于 2013-02-09T00:47:35.013 回答
0

优点之一是您可以为工厂方法提供易于理解的名称。它将帮助您轻松了解您的函数中的哪些函数在工作,并在将来轻松维护您的代码。看看这个例子,希望对你有帮助。

    public class Contact {

    private Contact(String displayName, String phoneNumber, int contactType){
    //do something
    }

    //then we will have few functon static to get constructor private
    public static createContactUnknow(String phoneNumber){
        return new Contact("","00000000",0);
    }

    public static createContactValid(String displayName, String phoneNumber, int contactType){
        return new Contact(displayName, phoneNumber, contactType);
    }
}

    //then
    Contact myGirlFriend = Contact.createContactValid("xxxx","000000",1);
    Contact unknowFriend = Contact.createContactUnknow("45454545");
于 2015-12-16T14:30:55.237 回答