为什么要重载构造函数而不是使用 return 自引用的方法?

Why overload the constructor rather than use methods that return self references?

我刚刚第一次遇到这种方法:使用 return 自引用的方法而不是重载构造函数。考虑 Selenium FluentWait 的示例用法:

   // Waiting 30 seconds for an element to be present on the page, checking
   // for its presence once every 5 seconds.
   Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
       .withTimeout(30, SECONDS)
       .pollingEvery(5, SECONDS)
       .ignoring(NoSuchElementException.class);

方法 withTimeoutpollingEveryignoring 每个 return 自引用。这似乎是一种绕过必须创建大量重载构造函数的方法。例如,您需要 23=8 个单独的重载构造函数定义,以允许初始化 FluentWait 的实例,省略或包含超时、轮询和忽略。一般来说,一个 class 的构造函数可以有 n 个可能的输入参数需要有 2n 重载构造函数定义(如果需要每个可能的输入组合)。使用方法似乎是获得相同功能的一种简化方法。为什么我不应该一直这样做?哪种方案比另一种更好?

重载构造函数和其他方法只是一种很好的方式,您可以通过这种方式让自己和其他开发人员更轻松地使用它们。假设您有一个 add() 方法。如果您想在 Java 中同时接受 2"2",您将需要重载构造函数以接受 Stringint

像这样:

public add(String number) {
    ...
}

public add(int number) {
    ...
}

构造函数允许创建实例的字段final,这对于创建不可变对象很重要。您还可以将检查添加到构造函数中,这将验证您的字段的不变量。要结合您喜欢这种方法的灵活性和使用构造函数的好处,您可以使用构建器模式。

这与 Builder pattern 非常接近,请查看那里的概述以了解该模式何时适用。

在这种情况下,您说 FluentWait returns self-references。它使对象可变。如果您有 multi-threaded 或并行执行,这可能会有问题。

This seems like a way to bypass having to create an inordinate amount of overloaded constructors.

事实上,它不在这里,因为每个调用的方法 returns 当前对象。
javadoc 明确指出。
对象在此处创建:new FluentWait<WebDriver>(driver)

这些是流畅的调用。
它避免了每次需要在对象中设置某些内容时都为变量添加前缀。

而不是写作:

Wait<WebDriver> wait = new FluentWait<WebDriver>(driver);
wait.setTimeout(30, SECONDS)
wait.pollingEvery(5, SECONDS)
wait.ignoring(NoSuchElementException.class);

你可以这样写:

Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
                      .withTimeout(30, SECONDS)
                      .pollingEvery(5, SECONDS)
                      .ignoring(NoSuchElementException.class);

还有一种流畅的构建器,它是一种以流畅和 thread-safe 方式实例化对象的方法,但这是另一回事。