Friday, September 6, 2013

Better-Setter-Getter

I must confess that it's very difficult to bring myself to write code with a long life expectancy in an alternative JVM language. Scala is slowly taking over and that's great. But if I'm working on an API, an open general purpose one, or some "important" layer within a system, the thought of not using Java doesn't even cross my mind. Not that those other languages are not good. But anyway, in this post I just wanted to complain that I'm tired of seeing, let alone writing getters and setters for bean properties. Since first-class properties don't seem to be on the table for Java, can we at least come up with a better naming convention? What would it take to have a tool supported, alternative Java Beans spec? The addition of closures in Java 8 is perhaps an opportunity and an excuse to revise this (e.g. event listeners can be specified more concisely). Perhaps it's already being discussed in the depths of the Oracle.

But let's start with the 'getFoo'/'setFoo' pair. For a "real world" example:
public class Customer {
  private String email;
  public void setEmail(String email) { this.email = email; }
  public String getEmail() { return email; }
}

That convention is ugly and verbose. For one thing why the need for the 'set' and 'get' prefixes? It is clear that if you are passing an argument to a function then you'd be setting. If there's no argument you are not setting, so you are probably getting as evidenced by the return value. Moreover, the fact that a setter returns no value is pure waste since you could always return this. Why is that important? Method chaining! Yes, method chaining is not to be underestimated and it's not just a trick of the conciseness-conscious coder. Since we in the Western world read left to right, programming languages are written and evaluated left to right. As a consequence, symbols to the left of the current position (of reading, writing or evaluating) tend to establish a context that could just be relied upon rather than repeated. When you put a semi-colon in Java, that's like a reset, context goes away, next statement. But if you are setting up a bunch of properties, as is frequently the case, your next statement will start by re-establishing the context you already had. That's more verbiage there on the screen starring at you and definitely kind of ugly. But it's also more work for the thing doing the evaluation. Values are returned on the call stack, so when your setter returns this, the next set operation doesn't need to push the object on the stack since it's already there. So there's a performance improvement there. Probably quite negligible, but I'd like to point it out because it ties to the observation that, in the kind of programming that consists of moving data in one form from one place to another form somewhere else, which is the bulk of so called "business" applications, less code does mean better performance.

The difference between:
Customer customer = new Customer();
customer.setFirstName("Bill");
customer.setLastName("Watterson");
customer.setOccupation("cartoonist");

and this:
Customer customer = new Customer().firstName("Bill").lastName("Watterson").occupation("cartoonist");

is not just a matter of taste. Well, unless you really have bad taste that is.

All it would take is for a couple of IDEs to support the new convention and a small lib that could quickly become ubiquitous. Or perhaps a big lib, something called betterjava.jar that would fix bad API designs from the early, and why not later, days of Java. I'm sure people aren't short of ideas as the Java standard APIs aren't short of problems.

2 comments:

  1. Problem with fluent getters/setters is the fact you cannot have something which works as soon as you have inheritance somewhere.

    Problem is : you often have inheritance on POJOs.

    I greatly prefer to rely on the Builder pattern, which allows to create immutable POJOs as well.

    ReplyDelete
  2. Why doesn't it work when you have inheritance? Can you provide an example?

    ReplyDelete