The Dopefly Tech Blog

<< The Dopefly Tech Blog Main page

Why variables.instance?

posted under category: AZCFUG on March 30, 2011 at 1:00 am by MrNate

Justin Scott left some comments for my book report on Object-Oriented Programming In ColdFusion, and I think the topic deserves a response. Justin writes:

I suppose I prefer to know the reasoning behind things like the "variables.instance" structure. I see it over and over again in CF OO discussions, but never a clear statement of the reason behind doing it that way, yet everyone seems to follow the pattern. I've not seen anything similar in any other OO reading about other languages, so it seems a little odd.
I, too, have seen this pattern in ColdFusion Components (CFCs). I can't find its point of origin, probably this blog from 2008 by Ben Nadel, but I will try to explain the thought behind it.

To start, I'll say that this is a ColdFusion & CFML specific design pattern. I think the reason it is strictly CF is because of the way object composition works, with regards to the dynamic nature, and how public and private members relate to their objects.

The short reason to why variables.instance is a pattern at all is that it draws the segregating line between the implementation and execution of an object. The implementation is what is written into your application, but during the execution, your object receives its dynamic data that makes an object unique. It is saying "this instance of this CFC has these instance variables." The variables.instance pattern keeps all of the execution details in one place.

Other than the potential feeling of correctness, this segregation pattern has another benefit, a way to set or get the instance variables as a whole without danger of overrunning or exposing the implementation details of an object. For example, if you have a struct that comes from an HTML form or a database, you can set the object's execution details in one fell swoop. Also for debugging, I find it helpful to be able to dump the execution details without the often voluminous implementation details (sometimes dozens of functions and other objects).

Too old to comment!
On Mar 30, 2011 at 1:00 AM Justin Scott (leviathan via darktech.org) said:
Thanks for taking the time to dig further into that. I found Ben's post a couple of days ago as I was doing some looking and I believe you summed up his take on it pretty well. It would have been nice if those details had been touched on in Matt Gifford's book. Perhaps a second edition. :) As I've done more and more experimenting with OO patterns over the last couple of weeks I can better appreciate why it's useful (i.e. having a getInstance() method in a base class that everything extends is pretty useful for debugging, as you mentioned. I still wish Adobe had made the CFPROPERTY tag the primary way to declare properties and set whether they're public or private rather than the this vs. variables scope, but this pattern is making more sense given their chosen way to implement variables.

On Mar 30, 2011 at 1:00 AM John Allen (johnfallen@microsoft.com or @google.com or @gmail.com) said:
Your last paragraph is spot on.

On Mar 30, 2011 at 1:00 AM Dan G. Switzer, II (dswitzer, who eats pengoworks.com) said:
The first person I can remember advocating variables.instance was Sean Corfield. I was using the same basic principal in my code (but I think I was using variables.private or variables.properties instead--I can't recall, it's been so long ago) and switched after seeing the trend of people using variables.instance.

The basic principal is it provides a simple mechanism for storing "properties" of your CFC that are private to the local instance, but yet segmented from other global variables.

This gives you really easy ways to return all the property values as a memento, w/out returning other global variables that you don't want exposed.

On Mar 31, 2011 at 1:00 AM Jaime Metcher (http://lagod.id.au) said:
I'm still confused.

@Dan:
"The basic principal is it provides a simple mechanism for storing "properties" of your CFC that are private to the local instance, but yet segmented from other global variables."

Isn't that the variables scope?

@Nathan: "this instance of this CFC has these instance variables."

Instance variables are the only kind of variables CFC's have, aren't they? Again, I'm not seeing the distinction between variables.instance and just plain "variables".

"The implementation is what is written into your application, but during the execution, your object receives its dynamic data that makes an object unique"

Isn't dynamic data the only kind of data CFCs have?

Ben's article is basically talking about objects with poor cohesion and how to work around that. There are some vague references to variables.instance making it easier to work with composed objects (do they mean mixins?). I can't see how this has got anything to do with either composed objects or mixins.

"I find it helpful to be able to dump the execution details"

And some stuff about mementoes. OK, I get this bit. I wouldn't base my programming practices around the memento pattern, personally, but to each their own.

Bottom line? I don't have a problem with any of this stuff really, I just think the reasons given are mostly incoherent. Doesn't it just boil down to "Because it's convenient"?

On Mar 31, 2011 at 1:00 AM Nathan Strutz (www.dopefly.com) said:
Jaime, thanks for your comments. This kind of feedback is what it takes sometimes to get people like me to relate things properly.

I think the confusion comes from the 3 layers of an object (yeah I'm making this up, it could be expanded, but stick with me).

First, there's the physical layer - it's the file, what's built into the template. Second, there are the implementation details - i.e., every bean gets a reference to a DAO, or every service has a pointer to the primary bean factory. Every instance of a User bean has a link to the UserDAO. But what makes it unique is the 3rd layer, something that represents a row in a database or a form field, something specific to THIS instance of the object.

It's saying that ALL object instances have these properties and methods, then they will have these extra objects and other configuration details which may be dynamic, but THIS object instance holds this unique data.

Built-in items show up in metadata calls. Composition details may show just as a getter & setter. They tend to be hard-wired or auto-wired but still dynamic, and this 3rd layer is unique.

When Ben Nadel is talking about composed objects, I think he's referencing the OO principle: Favor composition over inheritance.

Does it come down to convenience? Yes, of course, and I'll bend over backwards while standing on my head if it means it will be convenient for me later.

Finally, I didn't say it was a good pattern or a bad pattern. It's just a pattern that I noticed and Matt Gifford included in his book.

On Mar 31, 2011 at 1:00 AM Carl Von Stetten (http://centralsan.org) said:
I'm just starting to "get" OOP development in ColdFusion 9. I think your explanation of "variables.instance" made pefect sense. I think there might be a potential problem with using this convention, however. If you are taking advantage of CF9's implicit getters/setters paired with cfproperty, doesn't CF automatically create the variables established by cfproperty directly in the "variables" scope? Would this not preclude someone from using the "variables.instance" convention?

On Mar 31, 2011 at 1:00 AM Nathan Strutz (www.dopefly.com) said:
Carl, You are spot on. If you look at CF9's implicit property methods, they set to variables.X and this.properties.X. I haven't played with it enough yet to see if or how it can be cheated.

On Apr 1, 2011 at 1:00 AM Carl Von Stetten (http://www.centralsan.org) said:
I hadn't seen the "this.properties.x" before. If that is automatically created by CF9 when using implicit getters/setters, doesn't that break encapsulation?

On Apr 1, 2011 at 1:00 AM Carl Von Stetten (http://www.centralsan.org) said:
I just mocked up an example and tested this. CF9 does not automatically create "this.properties.X", only "variables.X".
Too old to comment!