Kiss My App

Wednesday, January 10, 2007

Properties as Extensions of Member Variables

There's a great debate on where to go with properties in Java SE 7, largely impart to the fact that the original suggestion at Javaopolis was so-- blah. I, myself, went back and forth a bit on ideas, but found the C# syntax to be the most promising. The reason being is ease of refactoring. All Java programmers are familiar and seem to want only dot notation for property accessors:

public class Department {
public Company company;
}

Company mck = new Company();
Department hr = new Department();
hr.company = mck;

Department appDev = new Department();
appDev.company = hr.company;


Well, that's the way normal public field accessors work today. But, what about encapsulation, being able to decorate or protect field assignment and access?

public class Department {

private Company _company;

public Company company {
get { return this._company; }
set(Company c) { this._company = c; }
}
}


Ah, very C#-ish :-) But, notice that our original code doesn't change:

Company mck = new Company();
Department hr = new Department();
hr.company = mck;

Department appDev = new Department();
appDev.company = hr.company;


This allows for easy encapsulation, while making it okay to do simple 'property' declarations such as public Company company;. We already have seen lots of field level injections within EJB3, JPA, JAXB2, etc.

I think one of the struggles with the JavaBean spec is that the syntax changes dramatically when your object decides to encapsulate some behavior or make internal changes. This is why I wouldn't mind seeing the JavaBean spec kind of fall to the wayside. You should be able to refactor introvertantly instead of extrovertantly (I made those words up).

Now the Pie in the Sky Stuff



To be able to provide better refactoring without basically declaring two 'fields': a member variable, and public property, we can imply a super behavior of a member variable, such that we just have:

public class Department {

public Company company {
get { return super.get(); }
set(Company c) { super.set(c); }
}
}


The issue though is how to do a public, read-only property, if the set is implied as protected or what not. Interfaces over properties would be allowed just like C#:

public interface IDepartment {
public Company company {
get;
set;
}
}


If Sun did want to add a new accessor, then use it for accessing meta/type information:

Binding b = new Binding(uitext#value, myDept.company#name);


Which would be read as bind the uitext's value to my department's company's name. Possibly the return type of company#name has methods on it such that you could add a change listener or get the read/write methods:

Property p = company#name;
Method rm = p.getReadMethod();
Method wm = p.getWriteMethod();
Class type = p.getType();
p.addChangeListener(new PropertyChangeListener() {
public boolean onChange(PropertyChangeEvent ev) {
if ("foo".equals(ev.getNewValue()) {
// stop propagation
return true;
}
return false;
}
});

5 Comments:

Post a Comment

<< Home