为何选择构造器重载而非返回自身引用的方法?
Great question! Let’s use Selenium’s FluentWait example to unpack why the fluent method-chaining approach is often a better choice than relying solely on constructor overloads.
First, let’s recap the example you shared, formatted properly:
// 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);
Now, let’s break down the key advantages of this approach over constructor overloads:
Readability that mirrors natural language
Look at that chain: it reads almost like a sentence. You immediately understand that we’re setting a 30-second timeout, checking every 5 seconds, and ignoringNoSuchElementException. If we tried to cram all this into a constructor, it might look like:Wait<WebDriver> wait = new FluentWait<>(driver, 30, SECONDS, 5, SECONDS, NoSuchElementException.class);Here, you’d have to guess (or look up) what each parameter does—especially the numeric values. No self-documentation here.
Flexibility for optional configurations
FluentWaithas more optional settings too: you could add.withMessage("Element never showed up!")or.ignoring(TimeoutException.class)on top. With constructor overloads, you’d need to create a new overload for every possible combination of parameters. That’s a maintenance nightmare—imagine 10+ overloads just to cover all permutations of optional settings. Method chaining lets you pick and choose exactly what you need, no extra code required.Avoids bloated, overloaded constructors
Constructors should focus on getting an object into a valid, basic state—not handling every possible configuration tweak. Piling all those options into constructors violates the single responsibility principle, making the constructor code messy and hard to debug. Each chained method does one specific job (set timeout, set polling interval, ignore an exception), keeping the code clean and modular.No parameter order confusion
Constructor overloads force you to remember the exact order of parameters. Swap the timeout and polling interval values by mistake, and you’ve got a bug that’s hard to spot. With method chaining, each value is explicitly tied to its purpose via the method name—no room for mix-ups.Supports immutability (if needed)
WhileFluentWaituses mutable self-references, the chaining pattern can also work with immutable objects (each method returns a new instance with the updated setting). Constructor overloads can’t handle this gracefully—you’d end up with even more overloads to account for immutable state combinations.
Don’t get me wrong: constructor overloads have their place! For simple objects with a small, fixed set of parameters (like new ArrayList<>(10)), they’re perfect. But when you’re dealing with configurable objects where users might want to mix and match settings, method chaining is far more user-friendly and maintainable.
内容的提问来源于stack exchange,提问作者Parabolord

