MattHicks.com

Programming on the Edge

Showing posts with label pojo. Show all posts
Showing posts with label pojo. Show all posts

The Death of Beans

Published by Matt Hicks under , , , , , , on Wednesday, July 01, 2009
My previous post was more of a rant about the frustrations of Java Beans:

Have Beans been holding us back?

I stated at the end of my post/rant that my next post would be about what I suggest as the viable successor to Java Beans. To that end, I begin my discussion about properties.

Though I would like to claim the idea of properties as all my own invention, I cannot and the concept was even new to me when I first read about them here:

https://bean-properties.dev.java.net/tutorial.html

This is not really a new concept, but rather an attempt in Java to solve the problem other languages like C# and ActionScript solve with encapsulated properties that allow you to make calls like:

object.name = "Something";

Though this would appear to a Java developer as a public field being set to a value, in these languages there is a feature to provide special functions/methods for "set" and "get" of the private field and simplifies getter/setter functionality while maintaining a clean and consistent coding experience.

Unfortunately there is no such functionality built into Java and if you want to provide anything beyond assignment of fields to values you must use methods to accomplish this.

With Java 1.5 comes generics which really for the first time make properties practical without a lot of extending of classes. So take a simple example:

public class MyTest {
private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}

Now, this is what it might look like using Properties:

public class MyTest {
public final Property<String> name = new Property<String>(null);
}

Properties have set(T t) and T get() methods that replace getters and setters, so a call to change the value would look like:

myTest.name.set("Testing");

Compared to:

myTest.setName("Testing");

They are about the same amount of actual code. What's great here though is that your Property object could contain much more additional functionality that you otherwise would have to inject yourself. For example if Property had the ability to addPropertyChangeListeners:

myTest.addPropertyChangeListener(myChangeListener);
myTest.name.set("Testing"); // Will now invoke myChangeListener when called

Further, you could have something like NotNullableProperty that extends Property and throws a NullPointerException if you try to call set with a null value:

public class MyTest {
public final NotNullableProperty<String> name = new NotNullableProperty<String>("");
}

Now a call to:

myTest.name.set(null);

Will throw a NPE and thus remove the need for you to ever have to check if "name" is null. This hopefully gives a slight grasp of the benefits this begins to provide.

Now, I mentioned above the article that really got me thinking this direction, but ultimately decided to write my own Property implementation because of some of the limitations and performance problems I saw with that implementation. Further, I had a lot of additional features I wanted to provide myself...and am often accused of wanting to write everything myself anyway. :)

This post isn't meant to push people to use a specific Property API but just to consider the methodology change even if they decide to write their own. After all, it only takes a few lines of code to create the base for your own Property class:

public class Property<T> {
private T t;

public T get() {
return t;
}

public void set(T t) {
this.t = t;
}
}

From there you can add any desired functionality: property bindings, value validation, property change listeners, observer/observable functionality, null checks, etc.

Though I don't want to push anyone to necessarily use a specific API, I will give reference to my own Property API for anyone interested in using it as it provides a great deal of functionality and I'm heavily using it in nearly all new programming projects these days and it supports filtering, change notification, property delegates, binding, read-only, adjusters, and much more. It is part of my xjava project:

http://xjava.googlecode.com

To see the source code for my Property API in SVN:
http://xjava.googlecode.com/svn/trunk/src/org/xjava/bean/properties/

Have Beans been holding us back?

Published by Matt Hicks under , , , , , , on Tuesday, June 30, 2009
I have been a Java developer for many years now and have always taken for granted some of the standards pushed on me from the beginning. Java standards such as basic Java Beans (aka POJOs) are supposed to make life easier by providing simple getters/setters that work with the private fields of your Object. For years I have neglected to challenge this as it seemed perfectly natural, and when I started to use Eclipse and could simply tell Eclipse to generate the getters and setters for my beans for me it made it that much easier to simply ignore all the extra code being created.

Unfortunately, over the years there have been some additional frustrations that have resulted from this approach as I wrote more code and attempted to do more complex things in my projects. As a developer trying to write more efficient and more elegant code these things have been a constant reminder that no language nor methodology is ever perfect.

The first frustration which I found myself struggling with as a new developer not using an IDE (that happily writes code for me) is the many lines of code to simply modify a variable. For example:


public class SimpleBean {
private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}


Notice that it takes up seven lines of actual code put a simple String into my bean and that's not counting the whitespace added to "pretty it up". Sure, as a noob coder it's tempting to do something like this:


public class SimpleBean {
public String name;
}


and be done with it. However, as a serious developer that's really not practical as it creates additional problems down the road when you want to add validation, remove the setter so it's a read-only field, notify something internally when the value changes, etc.

The next frustration I have with Java Beans is the fact absolutely EVERYTHING is a manual coding exercise. Take Java's Observer/Observable pattern for example. When I was beginning to learn Java I ran into the problem that I wanted to be notified when a value changed in one of my beans and stumbled upon a Observer/Observable tutorial and at first glance I thought, "Wow, this is really great and exactly what I want", until I realized in amazement they expect me to extend Observable and add an additional line of code to EVERY SINGLE setter call that I want to monitor. Come on, I was looking for abstraction to keep my beans dumb and simple, I don't want to add a bunch of extra lines of code to every method. Also, what if I'm already extending another class that I can't change? I'm sure many people might read this and think I'm just being nitpicky, and yes, I am, but I care a great deal about elegance in code and I was hoping for some sort of feature on my Field to "addChangeListener(...)" or something. Besides, every additional line of code is an added line that has to be filtered through when trying to read and debug and thus makes your code more error-prone and harder to manage.

Extending upon the previous frustration is bindings. There have been many a rant on the topic of bindings in Java and though there are many APIs and even a JSR set to solve the problem I have yet to see one do a good job. I myself tried to solve this with my MagicBeans project. There were many iterations of it, but the most elegant required AspectJ to monitor pointcuts on setter methods and notified listeners. It was a complete and elegant abstraction, but required your projects to be compiled with AspectJ which ultimately I abandoned as not worth the added pain.

Ultimately the Java Bean paradigm raises issues primarily in its requirement of the onus being on the developer to write any and all functionality. It disallows you to easily extend or reuse functionality in an Object-Oriented way because they are methods with statically typed fields they represent and though you can accomplish everything you might need to with beans they require a much greater commitment to custom code than should otherwise be expected of the developer in my opinion.

It is these things that have led me to believe there's a better solution, and I've settled on what I believe is the better choice, to which I will explain in-depth in my next post. :)