12 comments

[ 2.7 ms ] story [ 34.3 ms ] thread
Slightly off-topic, but I find it confusing to display only the second-level domain for links in cases like this. "google.com" makes me expect something different than "sites.google.com".

On a more related note, I enjoyed the yacoset site when it was posted here before and have read through it all. While sometimes a little fluffy, it's for the most part interesting and insightful.

I agree that sites.google.com needs to appear differently. It actually took me a minute to realize that article wasn't on a google blog (I'm reading on my phone). Feature request here: http://news.ycombinator.com/item?id=996374
I'd also add that the people who control salaries at a software company (particularly small ones) are usually not people who understand the development process very much at all.
In general, I agree. But "Only throw exceptions for the exceptional"?

The rationale for this guideline sounds like a performance-driven one ("since throwing exceptions will add unnecessary overhead"). This isn't always true, and contradicts a well-known Pythonic idiom (return victorious or not at all), which is a good idiom because it makes the client code easier to write and maintain (no testing return values; problems are handled out-of-band).

true and false are lousy arguments is probably the easiest to implement and most helpful tip on this list. I can't count how many times I have been reading a piece of code and forgotten what the "true" indicated in a call, or even seen code like:

  Frobnitz(true, true, false);
Maybe in Eclipse/NetBeans/etc, that code is meaningful with context-assist, but it certainly isn't readable for me. This also reminds me of a point that I can't seem to find in this list - "Options" objects help more in simplifying interfaces/configurations than many other solutions. It changes something like:

  Foo foo = new Foo(someObject, 3, 42, Foo.USE_FROBNOB, 27);
into

  Foo.Options opts = Foo.newDefaultOptions()
      .handler(someObject)
      .numThreads(3)
      .maxConnections(42)
      .build();
  Foo foo = new Foo(opts);
And allows for easy removal/addition of params.
This is exactly how you are supposed to do it. Similarly with "getters" and "setters," for those who use them.

Don't: setName(String name)

Do: setId(idObject idObject)

Makes it easy to expand the interface later.

Traditional Java Bean contract (default constructor, setters and getters), however, creates the issue of mutable state. Not saying that this is what you're advocating, but the builder pattern avoids this (by allowing immutable objects to be created).

That being said, much like other design patterns, the Builder pattern substitutes for something Java lacks: pass by name parameters. Sure, a third generation IDE (IDEA, Eclipse, Netbeans) can generate/refactor the code for me (which allows me to be almost as quick with Java as I am with Perl, Python and Scala) but it can't read the code.

Additionally, on the JVM if the builder is also an inner class, the are issues introduced with using it in some non-Java languages. I've ran into this issue when using Avro and Protocol Buffers with Scala (can easily be circumvented, by either modifying the code or using a Java "facade"). That in general shows a problem that design patterns pose when dealing with byte code-compatible but feature disparate OO languages (they pose problems in allowing the more powerful language's idioms reduce boilerplate).