[josm-dev] Jumbo Patch

Gabriel Ebner ge at gabrielebner.at
Sun Dec 16 18:29:52 GMT 2007


On Sun, Dec 16, 2007 at 12:56:19AM +0100, Petr Nejedly wrote:
> Frederik Ramm napsal(a):
> > 3. I don't like the privatisation because it bloats the code: You have
> > to implement a ton of accessors and they all just "pass through"
> > stuff, only a tiny percentage actually does something different. But
> > that's the Java spirit probably... 
> 
> Thats not just about the "java spirit". Correct encapsulation can save you
> a lot of headaches just for few lines of code

If encapsulation were that easy, we'd be doing it.  However, there isn't a
chance to abstract all the inner workings of JOSM into a simple getter
function, especially at these low levels of code.

Encapsulation isn't something you can achieve by adding a few
OO-mantras-of-the-week here and there.  It's a style of code.  You can have
state scattered all over the program, unrelated parts modifying internals of
each other and relying on the exact inner workings, and still have all this
trendy getters all over the place.  Likewise you can use common function to
interface the parts and build your program in separable parts and yet never
write a getter.

> (I certainly won't call a getter "bloat" and hotspot even inlines the code).

Getters are bloat, at least as they are written in java.  I'd bet those who
invented it were being paid for the line.  A simple public field takes what,
around one line?

  public Foo foo = new Foo();

Now let's add some getters and setters:

  public Foo foo = new Foo();

  public Foo getFoo() {
    return foo;
  }

  public void setFoo(Foo foo) {
    this.foo = foo;
  }

Wow that's seven times as much.  But we can do even better, let's add some
javadocs:

  /**
   * The foo field.
   */
  public Foo foo = new Foo();

  /**
   * Gets the foo field.
   *
   * @return the foo field
   */
  public Foo getFoo() {
    return foo;
  }

  /**
   * Sets the foo field.
   *
   * @param the foo to set
   */
  public void setFoo(Foo foo) {
    this.foo = foo;
  }

That's twenty lines of code!  And it's doing the very same thing as its
one-line counterpart above.  Now, I wouldn't mind using getters/setters if
there were some sugar for it, but this way they are not only taking away
screen real estate from more important things, but if you want to change the
type of the field, you've got to change the getters and setters, too, ...

And in many cases we'll be returning mutable hashtables/lists/... anyhow for
simplicity, which makes the whole indirection pretty much worthless as we'd
need to write proxy classes in order to maintain support for an old API.

> The fact that data primitives publicize their fields naked makes a lot
> of changes difficult and mostly incompatible. Having everything private
> and exported through methods properly would allow not only powerful
> evolution of the API, but also implementation of many optimizations
> in a transparent, painless way.

Currently, you can get the east-north coordinates of a node by getting its
eastNorth field.  We could wrap that in a getEastNorth() getter, which would
just consist of a single return statement.  Let's say we want to store this
presentation memoization in a central cache, maybe even with a spatial index.
And why just a single cache, we could have several so you can quickly switch
between projections.  Now it isn't enough anymore to just change the getter,
which of the projected coordinates should it return?

Most of the time the changes we make in a program are not restricted to these
simple changes (like changing the unit of a measurement) that java textbooks
are so fond of explaining.  We rather make changes that modify the whole data
model and would at best render the old getters inefficient.

  Gabriel.




More information about the josm-dev mailing list