考虑使用静态工厂方法代替构造函数

5
这与创建和销毁对象有关,来源于 Joshua Bloch 的书《Effective Java》。 条款1:考虑使用静态工厂方法代替构造器 该方法将布尔原始值转换为 Boolean 对象引用。
public static Boolean valueOf(boolean b) {
    return b ? Boolean.TRUE : Boolean.FALSE;
}

请注意,静态工厂方法与《设计模式》中的工厂方法模式不同[Gamme95,第107页]。本项目中描述的静态工厂方法在《设计模式》中没有直接相应之处。
作者似乎在谈论静态工厂方法和工厂方法模式之间的区别。这里到底有什么区别?
作为进一步的问题,BalusC此线程中提到了一个链接,在Factory Method下是java.util.Calendar#getInstance(),这是一个静态工厂方法,因此表明静态工厂方法是工厂方法模式的子集。

1
这可能会有帮助。https://dev59.com/kWsz5IYBdhLWcg3wCDl2 - Unknown
不太确定,但这个静态工厂方法的实例并不返回新的实例。它会用已经创建好的相应对象替换原始值。所以说“它不完全是一个工厂方法”有点正确,虽然它非常相似。简而言之:如果你定义一个静态工厂方法,必须返回一个新的实例,那么这就不符合定义。 - Fildor
我在这里看不到问题。 - Raedwald
3个回答

10

工厂方法模式

工厂方法是创建对象的接口。该接口的具体实现指定要创建的具体对象。

当客户端必须实例化一个对象时,但不应知道它是如何创建的时,使用工厂方法模式。

  +------------+       uses        +-------------+
  |   Client   |    ---------->    |   Factory   |
  +------------+                   +-------------+
        | uses                     | create()    |
        V                          +-------------+
  +------------+                          ^
  | SomeObject |                          |
  +------------+                          |
        ^                                 |
        |                                 |
+--------------------+   create  +------------------+
| SomeConcreteObject | <-------- | ConcreateFactory |
+--------------------+           +------------------+

静态工厂方法

静态工厂方法模式是编写清晰代码的一种方式。它是为构造函数赋予更有意义的名称以表达其功能的一种方式。例如:

List<String> newList = new ArrayList<String>(otherList);

上面的代码是什么意思?

newListotherList的副本还是ArrayList保留了对otherList的引用并只是将调用委托给它(就像一个包装器)?

我猜大家都知道上面的代码是做什么的,因为我们读了javadoc。然而,如果使用静态工厂方法,就不需要读取javadoc,代码会更加清晰。例如:

List<String> copy = ArrayList.copyOf(otherList);
SortedSet<SomeObject> sortedSet = TreeSet.orderedBy(comparator);

使用静态工厂方法,您还可以编写具有相同参数列表的多个“构造函数”,因为您可以给每个人另一个名称。这在使用“常规”构造函数时是不可能的。例如:

List<String> copy = ArrayList.copyOf(otherList);
List<String> delegateList = ArrayList.delegateOf(otherList);

1
以下是《设计模式》中“工厂方法模式”一节的定义[Gamme95, p.107]: “定义一个用于创建对象的接口,但让子类决定实例化哪个类。工厂方法允许类推迟它所使用的实例化到子类中。”
该模式不是一个单独的静态方法,而是一个接口(或抽象)方法,根据实现它的类进行调用。
查看以下示例: 工厂方法模式

既然我们正在讨论设计模式,请记住上面的例子包含不良实践(从构造函数中调用抽象方法)。

参见:在Java中从构造函数调用抽象方法是否可以?


1
谷歌搜索结果中弹出的工厂方法模式定义(来自维基百科)是:
定义:“定义一个用于创建对象的接口,但让子类决定实例化哪个类。工厂方法允许类推迟使用它的实例化到子类中。”
关键在于将工厂作为接口传递给需要创建实例的类。这意味着工厂方法的多个实现是可能的。
静态工厂方法使用静态方法:该方法是通过静态方式引用的,而不是通过接口引用。这意味着只有一种工厂方法的实现是可能的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接