Search

What the Quote?

"No hablo flamenco."

Laura Tripcony

"They're all flying to Hawaii to reenact Pearl Habor Day tomorrow."

Steven Rodgers

"Next week we're gonna powder-puff Monkey Butt."

Lawson Hise

« Code Monkey | Main| What the Quote? »

Get and Set: do you always need both?

Category lotusscript javascript
Earlier tonight I was writing a LotusScript class (which I suspect may be rather useful, and therefore intend to share, but can't just yet). Last night I was playing with some of the changes to the API in version 2.0 of Ext, and earlier in the day SearchDomino posted a tip for auto-generating Get and Set stubs for every private variable in a LotusScript class. All of this got me thinking of the concept of "read-only" properties.

For the longest time, the prototypal nature of JavaScript gave people the impression that it isn't even capable of making properties read-only, a perception which has since been debunked, and the Ext API is chock full of them. Most, if not all, of the "product object" classes in LotusScript have at least one property designated as read-only. Yet a surprising percentage of the custom LotusScript (and even Java) classes I see expose every object-level variable to modification, either as a Property Set statement, a setWhatever function, or simply by defining the associated variable as public. I'm not sure I see the benefit in doing so... in fact, I can see a few downsides.

I'll give you an example: in the class I was referring to earlier, there's a private String called lastError. All logging is handled internally via a throwError function, which overwrites lastError with a consistently formatted message. There's a public getLastError function, of course, because most of the public functions return a Boolean, so if a call returns False, I can Print or MessageBox getLastError to inform the user, administrator, etc. of what exactly went awry. But why would I need a setLastError function? Code external to the class shouldn't be able to overwrite lastError, because it won't have the information needed to format the message consistently unless that's exposed publicly as well, and there's no need to do that because the class is already handling all of that automatically for whoever is implementing an instance of the class. Being able to get the value is essential, but providing a vehicle for setting it just poses a risk that somebody is going to replace information that would have enabled troubleshooting with less useful data, or even cause it to appear that an error occurred when none, in fact, did.

In some cases, of course, a private variable won't even be exposed as a read-only property. For example, this same class contains a variable used to store an API handle on a NotesDatabase object passed to the class in the constructor. It's global to the class so that the handle can be established in the constructor, referenced as often as needed while in scope, then appropriately recycled when the time comes. No offense to the author of the above tip, but ain't no way I'm gonna expose that variable publicly; trying to save time by auto-generating Property statements just means I'll have to go back through and delete the dangerous ones... or skip that step and risk someone overwriting an API handle and causing memory leaks - perhaps even crashes - on their server.

Finally, the only real advantage I see to an extra statement or function to allow writes to a property is if something else should occur if the property is modified; for example, incrementing a count whenever a value is overwritten or updating all view/document references whenever the class is switched to a different database context. Otherwise, why not save time and just leave the variable public? Using Sets is often seen as defensive coding because you can't delete the underlying variable externally... but if you're exposing it to modification, someone can still change it to zero, null, or Nothing (depending on the data type, of course), and if the class is relying on the value to know what to do, that's just as bad.

What do you think? Am I off base here? Do you think every class property should be read/write, and if so, why?

Comments

Gravatar Image1 - I agree with you completely! You should only expose properties of a class when it makes sense to do so. Exposing all properties as read/write could, as you point out, be dangerous in worst case, or unproductive in best case.

Gravatar Image2 - I agree completely, too.

There are situations, where public getter and setter methods (or public member) make sense, like the title of a report.

In other situations, a read-only member (that is a private member, a public getter and no or a private setter) make most sense, like the stack trace in an error object. No one other than the error class itself should be able to set this information.

Then there are situations, where private members (no or private getters/setters) are most sensible. This is often the case for resources like a NotesDatabase or a File.

Even a write-only attribute may be the right choice - but only very rarely (think about how often you use Depositor access to a database). Perhaps there are different "users" of the class, which can independently add some information, but should not be able to see, what other added.

There are other reasons to make members private, but create public setters and getters:
- control the access by other means like user's roles
- log/count/... access
- hide the implementation of the class, thus it could be changed without modifying code, which uses the class
- add convenience methods like addX, appendX or clearX (with X is a list/array attribute)

One thing I really miss in LotusScript OO is class members - a unique variable for all instances of a class. But this is a completely other question.

Thomas
{ Link }

Gravatar Image3 - Creating getter and setter methods for all private members is rarely what you want, for sure. Still, Eclipse (and probably other IDEs) provide this feature for a long time now. You are free to delete any methods you don't need...

But there is one more important potential reason to use setters and getters instead of a public property: Lazy initalization. { Link }

This, of course, applies to read-only properties as well.

Post A Comment

:-D:-o:-p:-x:-(:-):-\:angry::cool::cry::emb::grin::huh::laugh::lips::rolleyes:;-)