ColdFusion Components As Data Types - Help Or Hindrance?
Posted April 9, 2009 at 2:51 PM by Ben Nadel
Over the last few weeks, I have done a lot of thinking about my pursuit of object oriented understanding. One of the points that I have explored thoroughly is the concept of using ColdFusion components as Data Types. While a data type is container of information, I think there is a subtle difference between a data type and a data container; and, it is this subtle difference that I have been pondering as of late.
A data type holds information; but, more than a simple container, the fact that it is a "data type" denotes a greater meaning to the container as a whole - a data type implies certain truths about the data contained within it. Take a String for instance - a string is a data type that implies a collection of character data. Because of this, you know that you never have to worry that accessing the second index of a string will return an XML object or a BLOB. That's part of what makes a String different from any arbitrary array of information.
So, can this concept of data types be applied to ColdFusion components? Well, certainly it could be - all that you would need to do is put the validation logic in the constructor and setter methods. But, the real question that I have come to ask myself is, should the concept of data types be extended to ColdFusion components?
At a purely philosophical level, I definitely like idea of using ColdFusion components as data types; there's a base comfort in knowing certain truths about an object based on its type alone. But, what I am really struggling to do is find any practical use behind such a constraint. In fact, other than this small comfort, I can really only see this constraint as causing friction rather than relieving it.
And so, I am going to abandon this concept. Not because I don't like it, but because I don't believe that it will make my application development easier. I don't believe that CFCs as data types adds any intrinsic value. And, by not living within this constraint, I open up the door to other efficiencies that will have a beneficial impact on my application development.
Kudos... not that you agree with me. You have broke out of the mold of social pressure being more powerful than active thinking. You did lots of active thinking on this one also... and that is a rare trait to be praised.
Sean C. states there are tradeoffs. For one person the type'd Class may be more pragmatic than for another. Yet it could be more about the apps and methodologies being used than the people using them. Either way... again, congrats for making a thinking decision. You have fortunate clients.
If you want to get technical about it, strings, numbers, structs, arrays . . . they're all objects. Simple objects, yes, but you have no problem thinking of them as data types.
Just think of CFCs as complex data types.
Sometimes I refer to strings, numbers, etc as objects, sometimes as data types. The terms are pretty much interchangeable, it just depends on with whom you're discussing them.
Right, there are tradeoffs. There's something about that I don't like; I think the discomfort is that I don't necessarily know enough to know what the tradeoffs are. But, I appreciate your praise - I have thought *a lot* about this and I simply don't see the use in the long run.
Exactly - which is what I was driving at when I talked about the benefit of knowing that a String is a collection of character data. However, applying the same mentality to CFC's, I am finding, limits us from being able to leverage a number of other efficiencies.
This reminds of when, a number of years ago, Hal Helms decided that he was wishing for strong typing and strict inheritance in CF for the wrong reasons. That is, that CF had some strengths to offer by virtue of allowing duck typing and direct injection that were actually just a totally different approach, and powerful in CF's own way. I continue to struggle with some of these same issues: do I return a single 'strong' data object or just a query? etc ...
Thanks for continuing to share your thought processes as you go along, it's a very useful foil to some of my own mental meanderings.
I think one reason enough to not use CFC's as data types is the lack of performance when it comes to object instantiation.
Usually a data type is a simpler construct than a full blown class (which is pretty much what a CFC is). For example in C/C++ the "struct" keyword is what you use to declare a new data type (also called a composite type) which you can then use to create new variables (see: http://en.wikipedia.org/wiki/Composite_type).
Due to the dynamic nature of CF we don't need to "declare" a data type to be able to work with structured data, we can just create a CF struct and add properties to it on the fly. The downside is that we have to be careful to always create each of the keys that would be expected to belong to the structure, unless you want to use StructKeyExists() all over the place (annoying). You could probably create a base struct once in and then use CF's duplicate() to create new variables from the base struct though. The code wouldn't read terribly nice though since you aren't really wanting to "duplicate" something, you just want a new struct with some default keys (and/or values). Perhaps some tiny factory would be better for getting these data types...
Ben . . . you have to remember . . . One Size Doesn't Fit All.
One thing that really blew me away recently was the Edmund framework. Super Smart Sean has some decision making components that are math functions. I never thought of classes acting as a math operator. OO is cool.
I've been using Coldfusion for about 3 months now, and I've seen how much of a performance hit Components can be on creation alone.
Component/Class objects were invented as a design feature to organize code and allow inheritance and polymorphism.
I too am creating a FormHelper of sorts, but it also builds the forms. One of the things I did was make each type of input a component data type. I have the TextField, and it's associated properties (Name, Title, Value, AllowNull, Disabled, etc.). I extend upon this with more data types like Email and Phone Number. Each input component manages its display, error checking (client and server side), and data.
It really is just a design question of how you want your code to look. However, in Coldfusion it's a question of whether it will hinder performance. Coldfusion is a fairly slow language, so code design is extremely important.
I do some game programming, and classes are superb for Math types like Vector, Quaternion, and Angles. However, I use it in C++ which allows overloading operators like + and - to do the Vector equivalent of addition and so forth.
Joel... any language is a slow language if you code poorly. If you have clusters of itterative components being created like a query translated into a component instance for each row of data... of course it will run slower. CF9 may have some ways to solve that for those who want to do it that way but that isn't the point. CF isn't slow just because one thing you do is an ANTI-Pattern for this platform. As you move from platform to platform there will be differences. Peter Bell has a itterative business object that might help solve those issue for you.
Bottom line: Don't engineer your software to match an OO pattern, use a pattern that works in your implementation.
@Joel If you're not doing things like John describes, check your JVM version. 1.6_10 fixes a bug in the JVM (1.6_4 +) that caused slow creation of class (CFC) files.
I spent a few hours this morning going to other extreme of non-typed mentality and CFCs purely as data containers with some generic behaviors built in.
It am finding it very interesting. I am doing some stuff that is making me feel very uneasy - but I am certainly stepping outside of my comfort zone.
I'll hopefully post part of it later today.
I took a look at the IBO by Peter Bell and it's a great component to manage properties, but components are more than just properties, they need to control their own routines and relationships.
I was schooled in the art of OO programming which is meant to stray away from procedural programming. Class Objects should maintain themselves and not depend on their global parent.
However, Components are still a fairly new flavor to Coldfusion and as you said CF9 should improve performance for OO programming.
I still believe Coldfusion to be a "slow" language in all aspects when compared to other scripting languages, I'd like to see some benchmarks though.
Yea, I barely caught note of that the other day, and am in the process of getting that done. Thanks
@Joel, there is a difference between a religion and an art. Let's not degrade the conversation to worship of programming gurus. Your schooling may help you and it may not. To know that you have to continue to learn.
Also, proceedural programming is not bad. Spaghetti code is bad. You can write code that is more dangerous with OO than without it! LOL, and I do appreciate you being honest about not even having benchmarks for your opinion.
Lastly... FYI. If you want a site to scale you are going to have to look beyond OO and data caching. Study how memCached has been used on sites like FaceBook and it will help you move in a direction that is scale and enterprise ready rather than creating an OO monster to scare away the proceedural monster. At the end of the day... you need a working solution that is sustainable.
I arrived at the same conclusion in my own CF OOP quest. I went the route of using CFC's as data types and found that at least for me, the drawbacks at the time outweighed the benefits. I'm glad I've found some support in this camp, especially somebody who's put so much though on the subject.
Of course there's always the possibility that at any moment, somebody could post a comment so profound, an example so earth shattering that I'd have to again spend the time to reconsider, but I guess that's the drawback/beauty of being in our profession.
Very true, CFC performance was a huge part in my decision to abandon the idea.
I'm fairly confident in saying that when it comes to site performance, the speed of the application language you use falls pretty far down that list. Data storage, design, and retrieval and application design will make or break your ability to scale.
I'd like to also note that the the end of the day, CF, like PHP, is just another language, it's speed will be determined by the platform it runs on and Adobe's not the only one making one any more.
If you use an OO pattern, doesn't mean you need to use it consistently throughout the application. You may use it for part of the app and for other parts you may do something different or use another pattern. I think when I was going down this path I was thinking everything needs to be OO from top to bottom, but as time went on I realized what I needed and didn't need in different parts of the application. I think the goal for most of us is to write nice clean code that's maintainable and that performs well whether we use a design pattern or whether we write procedural code. I've seen some frameworks that allow you to do one or the other or both.
Anyhow, don't get stuck on doing things one way, otherwise you stunt your growth as a developer.
I did a little experimenting with using the most dynamic nature of ColdFusion:
I set off expecting to fail (but open my mind) and actually ended up liking what I came up with.