Software is design, how ruby is better for that job than java

As a long time java developer and ... well ... at this point also a long time ruby developer, I've found some things about the ruby language are much less bothersome than in java. Groovy takes an interesting middle road, but only gets about halfway in my mind. I'll leave the runtime differences and the dynamic/static compiled/interpreted debates for other forums and just focus on the Focus on this one irksome quirk.

Property Accessors are too verbose

Java Definition
class Car {
    private Color color;
    public Color getColor() {
        return color;
    }
    public void setColor(Color color) {
        this.color = color;
    }
}
and to use it:
Car car = new Car();
Color blue = car.getColor();
car.setColor(blue);

The whole getter setter thing is a pain to me. The bean pattern used by java is just overly verbose. For all the OO purists, I get it, we need to hide the private variables and put them behind methods to abstract away the inner structure, but I'm so weary of 3x lines of generated code to accomplish this.

Groovy (1/2 way there)
class Car {
    Color color;
}
or (if you need to override a behavior):
class Car {
    Color color;
    public void setColor(Color color) {
        println color
        this.color = color
    }
}
and to use the class (either approach) the syntax is much better:
car = new Car();
Color blue = car.color
car.color = blue

In the first groovy example above, the actual class implementation is identical to the java example. It is much cleaner and obviously easier to read because it's missing all the cognitive overhead of explicitly defined methods, parentheses, and other java doodads.

In the second example, we've added some code to print the color to the console in the setter and still written fewer lines of code. This both reduces our typing/typo load, plus reduces our "100 lines of getters and setters" overhead. So, good marks to Groovy for striking a middle ground and allowing developers to do the easy stuff the easy way and only imposing the java crazy syntax tax :) when it's necessary.

Ruby
class Car
    attr_accessor :color
end
and to override the set color method:
class Car
    attr_accessor: color

    def color= color
        puts color
        @color = color
    end
end
and to use it
car = Car.new
blue = car.color
car.color= blue

While perhaps a little implicit, one might think that there weren't any methods at all, it looks like you're just setting and getting values. The advantage of the ruby approach is that when you change the underlying implementation, you can still use the simple syntax much like looking at java properties, but when you NEED the complexity of hiding things behind a method... you can do this you still have method declarations that are symmetric with how you call them.

One thing I hear over and over on this regard from die hard java folks: "But mike I can just use a tool that will automatically generate all that boilerplate and even automatically refactor all the names, so this isn't an issue". I disagree, what they're really saying is that there is a workaround they feel "isn't a big deal" to minimize the impact of this wonkiness, but I feel this is a broken window that is a foundational problem with java based solutions.

For detractors, let me start by stating that is is my opinion that all programming is design. If you disagree, then we probably won't be able to come to an agreement on the following statement, which is: "The most important part of a programming language is its ability to convey ideas clearly, succinctly, and unambiguously to other developers". The problem with java (and many other languages) is that it isn't designed to convey ideas to developers, its design instead seems intent on conveying instructions to the computer than it does to convey ideas to other developers. The ruby approach, in this regard, is much better.

References

Comments

Franklin Chen said…
Scala (statically typed, unlike Ruby or Groovy):

sealed abstract class Color
case object Blue extends Color

class Car(private var _color: Color) {
def color = _color

def color_=(color: Color) = {
println(color)
_color = color
}
}

object Example extends App {
// val car = Car() is illegal because not given a color
val car = new Car(Blue)
val blue = car.color
car.color = blue
}
Anonymous said…
the better code for Scala would be immutable one - create a new car object when you need another colour. This way you also don't need those ugly javalike setters and the code will shine.
Franklin Chen said…
Absolutely. I have been programming almost exclusively immutably for some time now when possible. I was just illustrating the exact equivalent to the Ruby and Groovy code provided.
Mike Mainguy said…
hmmm, the scala version is not too bad either...thanks!
Unknown said…
For all the OO purists, I get it, we need to hide the private variables and put them behind methods to abstract away the inner structure

Sorry, but for an OO-purits are evil. You are exposing inner-state whereas you should be communicating with messages. I like Ruby, but preferring a language since it makes writing setters and getters easier is like liking a gun because it adds a second sight specifically designed for aiming at your own foot.

PS- you should enable <q> tags in your comments if you can.
Mike Mainguy said…
interestingly enough, I worked on a java project a few months back where I didn't follow the getter/setter mantra. exposing methods that did things and methods that let you see things. It worked REALLY well, but every new java guy that looked at the code seemed to wince looking at it. Somehow it's ingrained in the java culture to build Anemic domain models

Popular posts from this blog

Push versus pull deployment models

the myth of asynchronous JDBC

Installing virtualbox guest additions on Centos 7 minimal image