4 ms·
This is cool, but I'm disappointed to see the horrid builder pattern show up again. Imagine you had to use StringBuilder every time you wanted to manipulate a S
by stickfigure 6y ago
This is cool, but I'm disappointed to see the horrid builder pattern show up again. Imagine you had to use StringBuilder every time you wanted to manipulate a String?
Just make all fields final and combine the builder and 'working' class into a single immutable object. Like String.
`build()` everywhere is syntactic noise, and you either lose immutable safety (by passing around builders everywhere, as in the examples) or composability (by passing around the 'sealed' objects). Builders are an antipattern that should only be used in cases where extreme performance is required.
- x87678r 6y agoI wish you were interviewing me. This is Java world you're talking about and if you can't squeeze a dozen Gamma Design Patterns into your code you aren't good enough.
- noema 6y agoThe main intent of Builder isn't performance, but to avoid a combinatorial explosion of constructors for every possible set of parameters.
- lalaithion 6y agoSo why have constructors for every possible set of parameters? Why VerbalExpression.regex() .startOfLine().then("http").maybe("s") .then("://") .maybe("www.").anythingBut(" ") .endOfLine() .build(); Instead of new VerbalExpression() .startOfLine().then("http").maybe("s") .then("://") .maybe("www.").anythingBut(" ") .endOfLine();
- szatkus 6y agoBoth are equally readable to me, but with the builder pattern you have an ability to fork a builder. Cloning objects in Java could be messy.
- stickfigure 6y agoWith immutable objects, every step in the fluent chain of calls is an independent fork of the full object state. There's no need to use java clone(); each method calls a private constructor that passes the object state (slightly altered, of course). java.lang.String works exactly this way. You're already used to the pattern.
- tpxl 6y agoThe builder allows you to have immutable objects. While I dislike builders and seldom use them, I dislike mutable objects even more.
- Tainnor 6y agoIn the parent's suggestion, you still have immutable objects. "VerbalExpression()" is a valid regex, namely the empty one. Every subsequently called method concatenates some new regex onto the receiver and thus builds a new regex (since regular expressions are closed under concatenation). Builders are used in Java* when you have an object which is invalid without passing in a bunch of parameters, but you don't want to have to remember the order of the parameters. But this is not one of these cases. There is one drawback, however: you do have to compile the regex into a FSA at some point and it wouldn't be good to do that for every intermediate regex. So I assume that the compilation happens in the "build" step. They could have just called it "compile", though. * named parameters in constructors seem a better alternative in every language that supports them, e.g. Kotlin
- stickfigure 6y agoFurthermore, with immutable objects there's no need to to have any public constructors at all. `REGEX.startOfLine().then("http")...` Since the start object is immutable, there's no reason to create new ones. Here's an example of this pattern applied to HTTP (my project): https://github.com/stickfigure/hattery https://github.com/stickfigure/hattery Avoiding repeated Pattern.compile() is a good point though.