« For those who can't go to Amsterdam... | Main | Flex beta 1 available tomorrow + Announcing free SDK »
January 09, 2006
Getters, setters, and the difference between Java and AS
After spending a good part of Christmas tinkering around with AS and Flex, I've decided to stop trying to put getters and setters around member variables unless needed. This may make my Java friends recoil in horror, but I think it makes sense.
When it comes to getters and setters, Java and AS are quite different, in that getters and setters are part of the core ECMAScript language, whereas in Java, getters and setters are done through a naming convention.
In Java, it is almost never a good idea to make member variables public. If you do decide to make member variables public and then later want to change the interface to use getter/setter functions, you will have to modify all callers of your interfaces, which is onerous at best and in many cases, not possible (expecially when you are creating code that is used by other people).
Meanwhile, in ECMAScript, the externally visible interface doesn't change when I go from a member variable to a getter/setter and back again. In some sense, the interface hiding is already accomplished in the language. Creating public member variables is "safe" in this sense.
Perhaps this is already obvious to all the AS-heads out there, but it took me a bit of time to get used to the concept. Now that I've flipped this bit in my head, I'm going to go ripping out all extraneous getters and setters from my code!
Posted by sho at January 9, 2006 12:56 PM
Trackback Pings
TrackBack URL for this entry:
http://weblogs.macromedia.com/mtadmin/mt-tb.cgi/6974
Comments
Glad you see the light! I posted a similar topic about a year ago...
Posted by: darron at January 9, 2006 01:38 PM
Dido
http://softwareaddiction.blogspot.com/2005/10/public-property-keep-out.html
The problem with Java is that you have to write over-engineered code
Posted by: Tiago Simoes at January 9, 2006 01:58 PM
Great article, Darron, and thanks for the link, Tiago.
Posted by: Sho at January 9, 2006 02:23 PM
That is what is cool about AS. In Java classes i started doing it also, for quick value transfer objects and internal classes that shuttle data back and forth between requests and such.
Too bad the style checker on the project forced me to rewrite it...
I am doing a lot of Ruby now as well, and there it is the same (as you can leave off the ( ) in a method call. so one also have the benefit that later on one can change it without refactoring a lot of code.
But honestely, with eclipse and intelliJ, what is wrong with some refactoring. As long you know you are not working on a API or some infrastructural part, how big is the chance, really, that later on you decide to hide a public member and instead handle it with a getter... and what is so bad in refactoring then...
really, i tend to become more and more pragmatic about this kind of thing...
Posted by: ilya Devèrs at January 9, 2006 02:48 PM
Totally agreed, Ilya, although it does depend on the size and nature of your project. For a one person Java project, refactoring is not a problem. For a project with lots of team members, or with an interface that may be used by other people, refactoring is sometimes not practical.
It never occured to me that Ruby's optional parentheses amount to the same kind of freedom. (I've never actually written a program in Ruby) Thanks for that insight.
Posted by: Sho at January 9, 2006 02:53 PM
Sho ... I agree so much with you, I'll write that in a book 18 months ago :-) Excerpted from the book:
Value Object Accessors
In J2EE, we would likely encapsulate our attributes as private attributes, with public getters and setters,
but in ActionScript, we recommend that you consider the following strategy that we adopt at
iteration::two.
In the simplest case in which we expect to be only getting or setting attributes, we choose to declare
the attributes as we’ve just shown, with public variables. Setting or getting attributes on a value
object is then as simple as this:
var account:AccountVO = new AccountVO();
account.accountNumber = “00310712”;
mx.core.Application.alert( “Account Number is “+account.accountNumber );
If the requirement on our value objects becomes more complex; perhaps we can do something a little
more clever in setting an attribute, for instance. Then we can encapsulate it by adding getter and
setter methods for the attribute.
5666 CH20 4/14/04 10:30 PM Page 23
24 Chapter 20 Flex Integration with J2EE
In ActionScript 2.0, we can use a feature known as implicit getters and setters and perform the following
refactoring:
public get accountNumber():String;
public set accountNumber( account:String )
{
this._accountNumber = “RN/”+account;
}
private var _accountNumber:String;
In this refactoring, we change the access of our accountNumber attribute from public to private, and
rename the attribute. (At iteration::two, our convention is to prefix with an underscore, although
many Macromedia classes use underscores in their implementations—and the compiler might warn
you if you happen to clash.) We then use the notation for an implicit getter and setter function, with
our function containing the same name we had for our public attribute. This then ensures that the
following code calls our setter—the implicit getter and setter ensure that a function call is treated as
if it were an attribute:
account.accountNumber = “00310712”;
In the preceding example, our motivation for the refactoring is shown as a requirement that
account numbers be prefixed with the fixed length string “RN/”.
This refactoring allows us to migrate from public attributes to public implicit getters and setter,
without affecting any client code (code that performs gets or sets).
We recommend this strategy over coding your own Java Bean style getters and setters.
Glad to see us agreeing on something !
Posted by: Steven Webster at January 9, 2006 03:18 PM
hmm, the cfm seems to have a hard time handling unicode...
Posted by: ilya Devèrs at January 10, 2006 03:45 AM
Steven: Great comments. Thanks. BTW, you and I know that we agree on things more than we disagree. :-)
Posted by: Sho at January 10, 2006 11:55 PM
I agree
Posted by: Steven Webste at January 15, 2006 05:10 PM