考虑提供静态工厂方法而不是构造函数

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

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

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

优点

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

缺点

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

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

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

唯一的问题是更多的代码要编写,但它仍然存在,所以你需要至少一些工厂的好处。

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

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

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

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

我会对问题的原始作者说静态工厂方法是一种工具。 像所有工具一样,它们具有最适合的用途,可以通过的其他用途,以及其适应性差的其他用途。 举一个现实世界的例子,锤子非常适合驱动钉子,足以顶住带有去钉末端的密封板条箱(撬棍仍然会好得多),但对于刨平粗糙表面毫无用处。

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

  1. 工厂方法
  2. 抽象工厂方法
  3. 单身人士模式
  4. 生成器
  5. 原型

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

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

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

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

考虑使用工厂方法的糟糕时间是:

  • 简单轻巧的物体

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

其中一个优点是您可以为工厂方法提供可理解的名称。 它将帮助您轻松了解function在您的function中的作用,并在将来轻松维护您的代码。 看看这个例子,希望它会对你有所帮助。

  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");