Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

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.



The main intent of Builder isn't performance, but to avoid a combinatorial explosion of constructors for every possible set of parameters.


So 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();


Both 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.


With 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.


The builder allows you to have immutable objects. While I dislike builders and seldom use them, I dislike mutable objects even more.


In 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


Furthermore, 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

Avoiding repeated Pattern.compile() is a good point though.


I 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.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: