I am NOT an OOP expert, I don’t play one on TV, nor did I stay in a Holiday Inn Express last night. I am fairly new to OOP. Please keep that in mind when reading this, especially if you wish to flame me.
The other day at work there was a discussion outside my office about the way some CF developers are handling the creation on objects and how we use the init() method. The way I handle init() comes from the way I initially learned about using objects. Here’s a snippet:
What this does is create an object and call the init() method at the same time. However, one caveat is that in you must specify a returntype (which needs to equal the object you are instatiating) for you init() method, and use <cfreturn this /> in the method.
One of my co-workers thinks this is a bad idea. He suggests doing this:
<cfset myObj.init(args) />
Why? The only thing I could really make sense of is that we are treating init() as a constructor (because CF does not have *real* constructors), and constructors typically do not return anything (at least, to my knowledge, not in Java -- which I think was the OO language being referenced in the discussion). And by having init() return something, you are ‘breaking’ some OO principles.
While I did not take part in the discussion (because I really didn’t think I could bring anything worthwhile in to the discussion), it got me thinking about the issue
I may be wrong (and if so, please correct me), but in Java, when you create or instantiate an object, you get an init-ed object back (the constructor is called automatically). So, while using
may ‘break’ some OO principles, creating and using the object, to me, seems more OO-like (or Java-like) because you get a fully init-ed object when you create it.
For me, at least, it helps me to understand OOP a bit more when I use
Are there any other compelling arguments for or against either of these methods?




8 comments
If you intend that init() should be called upon instantiation, every time, then write your code to reflect that.
Your method (which I use as well) ensures that no-one will try to use the component before it is fully intialized and allows all other code in that component to assume that init() has been run.
Class myClass = new Class();
The "new" keyword assigns the instance.
In CF we make our own constructors. Any CF developer not using an init() with <cfreturn this/> is violating best practices and would have a very difficult time convincing me why going against them is a good idea. Frameworks like ColdSpring rely on the fact that developers adhere to best practices... if you have a CFC with an init() method that doesn't return itself it would be incompatible with ColdSpring.
I think you're definitely right in this one. A few things:
>I may be wrong (and if so, please correct me),
>but in Java, when you create or instantiate
>an object, you get an init-ed object back
In Java, that's correct. When using Java from CF, you don't get an init'd Java class back. A Java class can have more than one constructor, each with a different set of arguments. Therefore, creating an init'd Java class in CF looks like this:
<cfset myObject = createObject("java", "some.java.class").init(someArg, another Arg) />
Well, it'd really stink to have to use two different ways of constructing objects - especially if you wanted to swap out a CFC for Java or vice versa - so it only makes sense to use the same format for ColdFusion.
However, that requires the init() method to return this. That's not as "un-OO" as a lot of people think, and it no way makes ColdFusion a less Object-Oriented language. In fact, OO languages have had "constructors" returning instances since before Java came around!
Smalltalk (and Objective C) both work in a sorta similar manner (to my understanding of them). Hell, in Smalltalk, you can call a "constructor" with some arguments, and the constructor may decide you want a different object entirely, and return an instance of *that* object instead of itself/"this"!
IMHO, creating the instance and returning it is *more* object oriented than C++-style constructor, because the responsibility for creation of the actual instance to be constructed is delegated to the class!
<cfinvoke component="FooObject" method="init" returnVariable="fooObjectInstance" argument1="fooarg" argument2="barArg">
because it gives me the benefits of OO, feels more "ColdFusion" rather than Java and works even if security-conscious admins have disabled "createObject" on CFMX 6 servers.
But seriously, comparing constructors to init() is really like comparing doors on a station wagon to doors on a Jeep. Jeeps are bouncy and fun, but they HAVE NO DOORS unless you choose to mount some... and they can be canvas or plastic or metal. Soft sided? Soft-top? Hard-Top? THAT'S NOT A DOOR, IT'S MADE OF CANVAS!!
Right... whatever.
Laterz (and hoping that last part made sense. hehe.)
application.obj.init(args);
That is not thread-safe. It creates an uninitialized application.obj that cannot safely be used by other threads.
application.obj = createObject("component","thing").init(args);
That, on the other hand, *is* thread-safe - application.obj only exists as a fully-formed, fully-initialized instance.
I also visit this site when I encounter problems with java...thanks!
weblogs java- http://weblogs.java.net/blog/kgh/archive/2004/12/m......
weblogs java
http://weblogs.java.net/blog/javakiddy/archive/200......
weblogs java- http://weblogs.java.net/blog/kgh/archive/2004/12/m......
weblogs java
http://weblogs.java.net/blog/javakiddy/archive/200......
Mazda plug wires
http://www.automotivemazparts.com/mazda-spark-plug...
weblogs java- http://weblogs.java.net/blog/kgh/archive/2004/12/m......
weblogs java
http://weblogs.java.net/blog/javakiddy/archive/200......
weblogs java- http://weblogs.java.net/blog/kgh/archive/2004/12/m......
weblogs java
http://weblogs.java.net/blog/javakiddy/archive/200......
Good luck...