Is It Time For "Practical" Object Oriented Programming (OOP)?
For almost the last two years, I've been trying to learn Object Oriented Programming (OOP) in ColdFusion. Coming from a strictly procedural background, the concepts of object oriented programming were new and wonderful and exciting and .... very difficult to truly understand. Along the way, I've read some great books like:
- Head First Design Patterns
- Head First Java
- Design Patterns: Elements of Reusable Object-Oriented Software
- Fundamentals of Object-Oriented Design in UML
I've also attended two Hal Helms "Real World OO" classes; I've watched many presentation on OO and refactoring; I've tried to build several sample applications with object oriented principles; and, I've blogged copiously on the topic of design patterns and object oriented programming in ColdFusion.
Now, two years later and what do I have to show for it? Without a doubt, I definitely have a much better understanding of some design patterns and I see how to decouple components in many cases. I am certainly a better programmer than I was two years ago, no questions asked. But, as far as object oriented programming is concerned, what I have found is that my exploration has delivered more questions than answers. Every time I think I am making progress, I come to realize that I only have more confusion over the "right" way to implement something. As such, I continue to write procedural code while trying to learn object oriented programming on the side.
After last week's OO-crisis and my shattering of what it meant for an object to be in a "valid state," I felt like I had come to some sort of cross roads. After the revelation, I felt like I wasn't making any more progress on the subject of object oriented programming. In fact, it seemed as though the few points that I did feel confident about might be totally wrong.
Needless to say, this event disheartened me. I took some time to reflect on my journey and I think perhaps it is time for me to give up my pursuit of OO-purity and simply accept "practical" object oriented programming. By this I mean that I think I need to stop wondering about the "right" way to use objects and just think about which way makes me more productive and makes my applications more maintainable. In the end, isn't it really only the later that has any practical value?
Obviously, I won't ever be closed the learning better ways of programming - I always want to know the "better" way; but, right now, I know that I am letting "Best" be the enemy of "Good." Until I can find that "best" way, I might as well employ good practices. I don't know what my next step is going to be but I think I might re-examine my OOPhoto application and see how I can refactor it.
Reader Comments
I feel sad having just posted this. I feel a certain kind of defeat. Like I wasn't smart enough to figure out how this all fit together. Not a great way to kick off the week.
Aiming for perfection is fun, but it doesn't get a lot done.
I approve of doing something you feel is not quite right, but still pretty good.
You are more likely to find the "best" way, while continually trying to improve rather than trying to achieve the best straight off.
..or at least that's my opinion.
Don't let it kick you around too much. I first journeyed into OOP in PHP last year and I've had my share of confusing, disheartening experiences. I severely doubt it's a lack of intelligence. One of my biggest problems with it was finding a de facto "standard" on the subject; of course there is no one right way of doing things, but that was all the more prevalent in what's not a "true" OO language. Sometimes OOP simply isn't the right solution.
I kind of have the same problem. As I learn more, I come to a cross road and have to go back to writing procedural code. It's funny that you mentioned this topic, because I wrote a post similar just last week.
@Ben,
Rather than defeat, I believe you have finally won. When I read your post last week, I was a little disappointed that you seemed to base your "incorrect" view on what another programmer (though one you highly respect) stated was the "right"/"correct" way. For years, I never searched for the "right" way - I just got tasks done as quickly as possible. In time, I started to learn about standards and best practices, and I put many of those into practice. But, in recent times, I've come to realize that no matter how hard you try to do things the "right" way - the way other people tell you is right - there will always be someone to tell you it's the wrong way. You said it perfectly in this post: "I think I need to stop wondering about the 'right' way to use objects and just think about which way makes me more productive and makes my applications more maintainable". Don't throw OOP away because you're not doing what someone else taught you. Use OOP where you can and when it will benefit you, in the way that makes sense to you. We all began programming learning by trial-and-error, and to be honest, I am still learning this way.
You're in good company, Ben. I've spent the last year watching every OO/Framework presentation that's come down the pike...trying to get a mastery of it all BEFORE I start my next GREAT project. I've been a procedural guy for years and I'm trying to break out of the mold and build applications that are more modular and maintainable. Many of my associates are in a similar situation.
I think, in the end, "Just do it" like the old Nike commercial says..do it to the best of your ability and then refactor later when you've learned from your mistakes.
Thanks for sharing your travels with us...we've all got the same sticking points it seems on our way to mastering our craft...I have learned a LOT from your blog and can't thank you enough for sharing your experiences with us!
Ben,
You need a hug buddy :)
Procedural programming is rather simple. As long as the process works, then the design is successful. Object Oriented designs are a little looser and there are many more opinions and guidelines on OO than on procedural programming. After all, there is no "Head First Spaghetti Programming".
A lot of times, OO Design can be analogous to painting a tree. The novice asks, "How do you paint a tree?" The expert says "It Depends".
There are no 'right' ways to paint trees, no matter what Bob Ross says. There are only ways that are less wrong.
So take heart, my friend. The right design is the one that best works for now.
{{{{Ben}}}
Dan Wilson
I echo a lot of what prior commenters said. I am by no means an OO expert but I think I understand it enough to use it well in my applications. Nonetheless, I was where you are a while back and it meant I took forever getting things done. In the end, I think OO is a continual exploration and even the so called gurus look back on applications they did and see how they would have approached things differently.
Embrace refactoring! :) While it doesn't mean that you ignore best practices, it means that you will find better ways to do things in retrospect and you can always go back and revise. You have to learn to balance getting things done and getting things done right when those things aren't always completely compatible. Its the beauty of what we do that we aren't stuck with something just because we did it that way before (usually the reasons that prevent change are organizational not practical imo).
Can't remember who said it, but the quote "In theory there's no difference between theory and practice" comes to mind.
I think it's wise for us all to keep studying, learning, and pondering the wonders of OO.
But in some cases it really is just theory.
At the end of the day we have to make stuff work, and work well, which will always mean compromises as compared to the pure OO design that can only really exist in our heads.
But that doesn't mean we should stop learning and thinking about all this stuff in the same way, because even if in the end we have to compromise to make things work in the real world, the pursuit of OO perfection makes our practical implementations far better in the long run.
I'm with you all the way, Ben, and it's nothing to feel defeated about. I learn all I can about OO, try to let it sink in, and then use those concepts in a practical way that works for me. I've stopped worrying about if it's the "right" way. Sure -- a lot of times after the fact I find I could've done things "better" -- but it's all about practicing your craft and learning from your "mistakes."
Even Hal himself says "If you meet the Buddha on the Road, Kill Him."
http://www.halhelms.com/blog/index.cfm/2008/2/9/If-You-Meet-the-Buddha-on-the-Road-Kill-Him
So even HE would tell you not to take what he says as gospel.
While OO is a powerful tool, it's really just that, a tool in your toolbox. It's not the "be-all-end-all perfect way to develop any application". Not everything can be solved by OO, some things are inherently procedural.
For example, my dirty little secret is that I really don't like using Mach-II, Fusebox, Model-Glue or any other "MVC" framework, because I still feel the best model for a web-request is a single CFM file, which reads some data, does some processing, and outputs a text file to the browser. That's a pretty procedural viewpoint, but really, it works amazingly well. It's the reason that ColdFusion and PHP are really popular, and people like programming in them over Java and ASP.NET.
However, as soon as you start building a system, areas where you're repeating yourself become evident, or when you're pushing the same chunk of related data around in labyrinthine array/hashtable data structures, and that's when OO starts to become important.
The trick is really recognizing when the OO tool is appropriate to the task, and when it really might serve as more of a hindrance than a powerful tool.
Ben, I feel your pains here. I've been doing CF development since CF 2.0. I struggled with OOP concepts for a very long time. It wasn't until I started working with OO languages, primarily AS3 and now Java, that I started really getting some of the concepts that I was being taught. I am still learning on a daily basis, but at a much faster pace than ever before. And having more "Oh, now I get it!" moments.
Frankly, and I know some people won't like to hear this, I believe that CF was holding me back to a certain degree in this area. CFML doesn't force these concepts on you, and even implementing OOP concepts in CMFL can be hackish. And there are even cases where CF forces you to break out of the OO paradigm for proper performance (using typed structs instead of beans for Flex apps is a primary example).
As an afterthought, i guess the acronym for Practical Object Oriented Programming will never be popular eh?
^^ yeah that's what I was about to say, it seems like you are calling for more POOP ? ;)
Could it be you've been held back by your language of choice, which IIRC was initially a wrapper to avoid you having to mess with all the the nasty OOP of Java. It's a bit like saying 'I've been finding it hard to learn stick shift while driving my automatic'. Why not try the other end of the spectrum, play with Ruby or something similar, if only for a fresh perspective on the concepts?
There is no Right or Wrong, only Cause and Effect.
So we must detach our egos in order to see things with greater clarity, this is where I believe your problem is Ben. Who cares whether an OO design is right or wrong, the only judgement is what are the possible effects of that design. Intelligence is the ability to accurately gauge the effects of a design to an appropriate depth - I think you handle this extremely well and with a scientific mind.
Right and wrong are human constructs. They are fine when dealing with humans but will get in the way of your design process, as your focus will be in the wrong place.
Also remember it is your choice whether you want to be right or to be happy, the two are rarely the same.
ha. POOP.
Like the others I can only reiterate there is no One True Way(tm). Once you get beyond the basics, there are only tradeoffs really - and that is core to every design pattern (and something that almost no presentation ever touches on!).
If you make a choice to model your problem domain in a particular way you are trading off one set of options for another. We often pick simplicity over flexibility or vice versa (not that they are opposites, just that many choices trade them off against each other - your post on proxies to decouple services and domain objects was a good example of picking flexibility over simplicity).
It's better to create *a* solution than get stuck in "analysis paralysis" because you can always go back and refactor later. Over time, you get better at making the trade offs as you go and deciding which ones are worth it in each situation. Never be afraid to go back and "undo" a decision because the business forces change over time and can invalidate - or reverse - the value of any given trade off.
I started doing OO just over 17 years ago and there was a distinct lack of good learning material around then so the temptation to try to do things the "best" way was much less than it is now. I made lots of mistakes and gradually learned from them because I made my own code harder to maintain for myself than it needed to be. Over time, I learned (some of) the tradeoffs that made for more maintainable code. These days the options can be a bit overwhelming by comparison.
A story I like to relate is this: a few years back I was at CFUNITED and told an attendee that he shouldn't expect to "learn" OO in just a few weeks or even months. I told him "OO is hard". He became very agitated, assuming I was telling him he was too stupid to learn OO. The problem is that people seem to think OO is something they can check off a list: "Learn OO. Done!" whereas it's really a journey. I actually think the "Head First" style books contribute to that a little bit - many people seem to assume once they've read a few of those books, they should be good to go... which just isn't the case.
Something I would encourage *everyone* to do is to read the first two paragraphs of the "gang of four" Design Patterns book, Chapter 1, Introduction. In fact, I may do a blog post that simply quotes those first two paragraphs because they really do speak to the sort of problems people have when learning OO...
A few people did bring up some good points about Language development. I'll tell you, nothing has helped me pick up OO, and the practicalities and theories of it as much as learning Flex/ActionScript, and poking around creating some C# dekstop apps and Java desktop apps.
Sometimes having the forced formalism of a "strong OO" language like AS, C#, or Java can make you see where a lot of these patterns came from. Some patterns, like MVC become a lot more intuitive over the web than they are on the desktop. Others, like Dependency Injection are just the opposite... It's hard to use them well on desktop applications, but over the web they make perfect sense. Still other patterns, like Unit Testing, have obvious immediate benefits in both environments.
Oops, meant to say that MVC was more intuitive on the Desktop than on the Web...
Often times, when I am feeling very emotional about something, I like to translate the situation to something that I can separate from emotionally:
The Gym
How would I handle this situation in the gym? How would I feel about this in the Gym? Often times, I find that I can make a better decision when I use this approach.
So, let me try to embrace that once again here. In the gym, there is no "right" workout program. Right now, I am using Chad Waterbury's "Huge in a Hurry". Before that, I've tried super slow programs, 5x5 programs, body part programs, full body programs, splits, etc. Each of them works to some degree because we don't know everything about fitness, and we need to keep variety to keep the progression working.
Like I said, there is no "right way" to workout. Everything works at a certain time based on your context.
So, what is the "Right" program really?
As many fitness professionals will tell you, the "right" program is the one you actually do! Meaning, no program is "right" if you cannot be motivated to stick to it. It loses its value completely if you don't utilize.
Taking that mentality and bringing it back to OO, I guess the "right" kind of object oriented programming is the kind that I can actually leverage! If I can't leverage it, then it serves no value.
That's not to say that my techniques and understanding cannot improve over time (I sure hope they continue to do so); but, in the meantime, I have to pick a strategy that I can actually use and get value out of.
... that is to say, I agree with what ya'll said :)
Also, I am working on learning Objective-C for the iPhone. While the syntax is odd, it is an OO language; so, we'll see how that influences how I feel about CFCs.
Nothing I have read so far, however, makes me feel that ColdFusion has been a limitation at all. The real differences, as Adam mentions, is that Desktop apps are fundamentally different than web-based apps.
Ben,
Congratulations, you have graduated from ColdFusion OOP 201.
ColdFusion is not an object-oriented language. It approximates some of the concepts, but if you try to make a CF application fully OO, it just doesn't work, and you architect yourself into a corner, maybe several corners.
"Pragmatic OO in ColdFusion" is a much harder concept to understand, but once you do, you'll wonder why it wasn't so obvious to you. You shouldn't use CF for things it's not good at, and pure OO is one of those things CF isn't good at. A blend of things you used to use in procedural CF - the things that ColdFusion is GREAT at, like queries and structs - along with fundamental OO concepts like encapsulation and decoupling - helps you make ColdFusion work even if the results aren't "pure" OO.
I will be talking about this at my cf.Objective() talk: "What to Do When OO Fails You in ColdFusion". If you haven't worked out some of this, and you're attending CFO this year, I think you'll enjoy the preso.
Ben, I feel your pain here. I've programmed in many languages for almost 15 years, varying from C++ and Pascal to PHP and ColdFusion, yet I still struggle. I will say that I agree strongly with Brian Meloche's statement of "...gratuate from ColdFusion OOP 201". Many people have mentioned it; it isn't the "right" way to do it, so much as is it the "best" way to get the job done.
And I also think it's great you are learning C. You will find that solving *different* types of code problems will expand your outlook on how to solve architectural issues in general, and that is ALWAYS useful.
Happy Coding Ben! As always, love the blog man.
The goal shouldn't be OOP. The goal should be maintainable, extensible, shareable, easy-to-test, easy-to-produce products.
How has your journey changed your view of how to achieve these goals? Maybe a top-10 list of lessons-learned?
I was heartened to see that your post generated so many encouraging comments. What a kick-ass community!
The only thing I can add is this: the object-oriented paradigm does not require greater intelligence, merely a different style of thinking. Never doubt for a second your supernatural aptitude for programming.
Learning any new style of thinking takes time. If the particular shape of your brain makes that learning an uphill battle, then it will take even longer.
Hardcore functional programming is a bit of leap coming from either the procedural or object-oriented paradigms. Pass a function that returns a function that takes a function to iterate over an array of functions... Some people are naturally suited for this. They looooove languages like JavaScript and Scheme. Others find it goofy and/or creepy.
You also face the challenge of a global programming culture that has fixated on the Java / Gang of Four vision of what object-oriented programming is. Smalltalk, Python, Ruby, and Objective-C have different ideas on the matter, and are barely represented in print and online literature at all.
Other commenters have suggested that OO might not be the best fit for the type of applications you find yourself building. They have also suggested that using OO in ColdFusion is awkward and uncomfortable, like making bread with a nuclear submarine. I agree heartily with all of the above.
So go easy on yourself, maestro! You still rock. :)
Ben,
Prototyping is often the best way to go. See Christopher Alexander's work in art and architecture and also the "Theory of U". In both cases, allowing a process to unfold and emerge can result in a better outcome than trying to get it right from the first iteration.
Cheers,
Murray
Not that I want to get you to hang out your dirty laundry in public, but some arm chair psychology is guessing that you're the type of person that when you do something, you want to know a lot. And that's maybe driving you to think that you should be more "expert" in OOP right now then you area. I wouldn't worry about it.
Curious about your comment about not using it in day-to-day apps. Are you sure you're not using some of the things? And could there be more concepts that you could borrow and put to use? Using more for the day job should help you get a better feel for OOP. It should also present you with some problems that you hadn't thought about before.
Sean Corfield wrote: "A story I like to relate is this: a few years back I was at CFUNITED and told an attendee that he shouldn't expect to "learn" OO in just a few weeks or even months. I told him "OO is hard". He became very agitated, assuming I was telling him he was too stupid to learn OO. The problem is that people seem to think OO is something they can check off a list: "Learn OO. Done!" whereas it's really a journey. I actually think the "Head First" style books contribute to that a little bit - many people seem to assume once they've read a few of those books, they should be good to go... which just isn't the case. "
I am not going to argue that Sean is wrong, because he is not. And that is the problem. He should be. He should be wrong. The story should go something like "there was an attendee at CFUNITED that said he had a problem with procedural coding, includes and copy and paste. I told he he should try OOP because it is very easy since it replicates how we see the world outside the computers. He thanked me for the advice and lived happily ever after"
That is how it should be. When we want to build a bookshelf at home, we do not normally think about what books we are going to put in it, except for the size maybe. We do not consider the possibility of making the bookshelf reject books by John Doe or throw the book back if we try to insert a Kurt Vonnegut novel in front of Isaac Asimov. We never consider if the bookshelf cares if we are reading anything and which books have been read.
If we, on the other hand, program a bookshelf we get all confused.
I don't think it is our fault. Or, of course it is "our" fault since OOP is a human invention. But it was invented by nerds, not by carpenters. Probably by the same type of people that invented German grammar. No, I am not saying there is anything wrong with nerds or linguists in general, but for practical use there is a limit on how formal you can get. A bookshelf is a simple thing, still there is hundreds of thousands of variations out there, almost each one of them fully functional. Still there is a constant ongoing work among furniture designers on how to find a better way of doing it.
Same goes for architecture. Houses. They become more and more standardized and functional. But the reason is mostly economical. If there is money, they leave the standards and experiment.
And that is after many thousands of years of trial and error.
I think that, at this point in history, we should take all "rules" within programming with several grains of salt.
Although I wouldn't say it's impossible to learn proper OO in Coldfusion, it's definitely going to get in your way. Try learning OO with a language that implement OO correctly. If I tried to learn this stuff in Coldfusion I'd have given up. My recommendation is to use python. Its got an excellent object model.
That being said, don't feel too down on yourself. OOP is hard. Also, even if you do find the BEST possible solution to your problem, I guarantee a few months down the road you'll find an even better BEST solution. That's just how it goes.
I think going for what is practical is the point there and thus what makes youre code cleaner and more maintaible/logical... But for some things such as speed, sometimes there is trade offs. Like CF is really slow for any large amount of CFC objects compared to native OO languages, so for record sets cfquery is the way to go IMO as it still gives great speed.
As for learning native iPhone development, I am currently doing the same myself and so before learning the superset - Objective-C, I learnt the basics of C. I must say I respect C at a low level as it is used to build most of mac os and the original linux/unix (cant remember exaclty) but I would have to say that it is terrible... there is no logic in any of the function names and zero consistancy - just becasue it is for low level programming doesnt mean that it has to be stupid. lol.
Objective C is somewhat better, but the syntax for that is again stupid - mainly just the method signatures + messaging, but once you get used to it, it's ok :D
I take it youre using a mac book or something? At least they are awesome, iPhone is awesome and xcode is a pretty nice ide :)
GL & HF
Hey Ben!
I like very much what Sean said about tradeoffs, and in my mind I just translated it into the word "options". The more complex a system, the more options you will have to choose the objects that will relate with each other in that system as a model of the problem the system should solve, and structure the way those objects divide up the responsibilities and message each to get the job done.
I was struggling last night for hours over a "simple" decision, whether to incorporate remote Ajax calls into a ColdSpring remote proxy architecture in a ModelGlue app, or just leave it somewhat hacked together, letting the few Ajax calls move directly via a "RemoteGateway" object I set up quickly. In the end I decided that my client isn't paying me to perfect the use of OO in his app, and left it, somewhat imperfect from an architectural standpoint, but very much good enough for my client. OO seems to stand for OnlyOptions, lots of 'em.
I really like those 4 maxims you posted for the warrior. I think the third was "don't assume"? I was thinking that normally we would interpret that third maxim to apply to the other, but it seems all the more powerful if we apply it to ourselves, and take everything we judge about ourselves to be an assumption that isn't true.
Some great contributions here Ben that hopefully show you that you shouldn't be doubting yourself when it comes to learning OO or your ability to do so. It sounds to me like you are somewhat of a perfectionist when it comes to these things and what to know 100% that you are 'doing' OO in the perfect way. Never going to happen. :)
Your gym example was spot on.. There are tons of ways to workout but none are going to be effective unless you actually choose one and get moving. Every day on a new regime is an opportunity to learn something new and find you own way.
I was *exactly* like you when I started looking into OO programming.. I got so hung up on the right way to do things and how to use the design patterns. Service layers, gateways, bean this, bean that.. It did my head in. I really wanted to feel that I was doing it right and it became debilitating.
Anyway, in November 2007 I started a contract building a large .com site and decided to ditch all of the 6 years worth of my procedural codebase and jump straight to:
ModelGlue
Coldspring
Transfer
OOP
It was a massive jump and I had to learn so much as I began building the site. I must admit it was very hard at first, but after a while things started to slot into place. Rather than trying to master all design patterns under the sun I ended up focusing simply on trying to encapsulate as much as possible - building a clear and consistent API into my model. I also adopted the service layer pattern with a service layer per application area (e.g QuestionService, UserService, LogService). Each service would have an associated Gateway that took care of all the Transfer calls and custom SQL etc.
This kind of thinking, along with MVC has been a real revelation. It's really got me thinking about separation of concerns and building highly extensible applications. It's nice to know that there is only one place to access various pieces of data and functionality - no more scouring through multiple templates to update queries. :) It makes things so much easier to manage and scale.
I have also found that seeing Transfer objects as business objects with actual behaviors as well as data has really helped to cement some of the core concepts in OO. I now think in terms of the domain model - what business objects are needed - rather than what data needs to be stored in the database, then working upwards.
I'm by no means an expert at OO, in fact I often wonder how much I really know but I do feel that this journey has been a massive benefit to my skillset.
I recommend that if you are able to, take one of your projects and commit to building it using an OO framework or using some of the techniques you've been learning. Having an actual paid job to work on can be a great way to move to a new more practical level.
I've recently been considering how to build my next site using my own MVC framework. Something more lightweight than ModelGlue but which still separates concerns and is nicely extensible. I'll probably just throw Coldspring into the mix to handle the bean instantiation and caching and then create my own controller and view layer.
Should be another fun learning experience.
Sorry for the long post.. :) Just thought i'd throw my take on this into the mix.
It's not like you get a prize for writing the most object-oriented application. I think it's important to keep in mind the objective, which is to create programs that are maintainable and extendable. If you're using DAOs your already way ahead of
inline embedded queries. If your using MCV you're already way ahead of someone using page after page of procedural code. If your doing automated unit testing you're already way ahead of someone
still doing manual testing. Can you make a change and go "sure, five minutes" rather than going "oh God, I have to do a search and replace, find out where that value is set, and then click through the whole app to make sure I didn't break anything..."?
@David Stamm, you talk about functional programming and mention JavaScript in the same paragraph - not sure connection you're drawing there?
Also, you say "You also face the challenge of a global programming culture that has fixated on the Java / Gang of Four vision of what object-oriented programming is. Smalltalk, Python, Ruby, and Objective-C have different ideas on the matter, and are barely represented in print and online literature at all."
The "Gang of Four" book does not use Java to illustrate patterns, it uses C++ and Smalltalk (so Smalltalk is center stage in the definitive book on patterns). A Java fixation would lead people to "Core J2EE Patterns" - is that what you meant?
To people who say CFML is not an OO language: why?
What do you think is the problem here that prevents CFML from being an OO language or that causes CFML to get in the way of learning OO?
Thanks for all of the feedback guys. I am definitely a bit of perfectionist when it comes to code - there is comfort when you believe that the way you are doing something is optimal. Not that everything I am doing is optimal, but with something as foreign as OOP, there is an especially strong drive to get there in attempt to feel more comfortable.
Utlimately, I believe I will go with many of you have suggested - the goal is to write maintainable code. I think that that is what my primary goal was from the start; however, I guess part of me felt that that was not obtainable without a more solid understanding of OO principles.
Although, that is not completely accurate. I think I *do* understand the principles of OOP. What I continually struggled/struggle with is the implementation of these concepts in real-world code.
I think I need to take @Glen's suggestion - review all the OO learning that I've done to-date and come up with a list of the things I've learned and what seems to work and doesn't work for me.
Sean, to answer your question:
I am an OOP novice, but what I can tell you is that after 11 years of doing ColdFusion and 4 years attempting to get a real grasp on OOP using CF I still struggled. After 1.5 years of doing ActionScript development and a few months of Java, I started to really grasp many of the OOP principals I did not get before.
This isn't saying the language itself is necessarily at fault, it could very well be the lack of proper documentation on the matter, or any other number of factors. I found that by working in a language that forced me to write OO I was able to make progress much faster.
To date we still do not have an IDE that is capable of handling OOP development with CFML. I understand this also is not the fault of the language, but it certainly takes away from the ability to use the development tools as an assist.
Combine these with the fact that CF has huge performance issues instantiating CFCs, thereby forcing one to consider alternate, non-OO methods (typed structs!!!!!!!!!! this irritates me to no end), and I am left with the impression that CF still has a ways to go before I can consider it as a serious platform for OOP.
To be clear, I still love CFML. it is a great templating system for websites and HTML applications, and provides many services that would take enormous amounts of time to build in other languages. So, for me at least, CFML will be a complimentary technology I use in conjunction with other languages.
I understand you come from a true OOP background, and have many years experience prior to CFML developing OO apps. From your viewpoint you may not experience the same struggles that a developer who learned to program procedural code with CFML has. You already "got it". :)
"
To people who say CFML is not an OO language: why?
What do you think is the problem here that prevents CFML from being an OO language or that causes CFML to get in the way of learning OO?
" -- Sean Cornfield
Now that sounds like a simple blog post that could kick off a thousand comments. :)
@TJ, well, that's why I recommend CFers learn some radically different language to get a completely new viewpoint on development (Smalltalk, Prolog, Haskell...). Sounds like using different languages gave you that different perspective which is good.
I will admit to benefitting from being able to bring my C++/Java OO experience to CFML - and from starting out with CFMX (so CFCs have always been part of CFML for me).
As for the performance problems, whilst CFC creation is slower than Java object creation, I'm not finding it hampers my designs. I can't imagine a valid use of objects where CFC creation is too slow - outside the oft-quoted DB query that yields large numbers of objects (to which I say: go try doing this with Hibernate and Java and you'll find that returning thousands of objects in an array isn't the ideal approach there either :)
I like to echoes some of the commenters here.
Software design is ALWAYS about compromise. At times, a practice is good in terms of performance, but lags around when it comes to expressiveness. Some practice is hard for a fresh programmer to understand, requiring deep understanding of OO but resulting in much more maintainable and easier to manage in the long run. All the time when you make decision in design, you need to balance between one thing or the other, or somewhere in between.
That said, sometimes we may feel that we don't have enough knowledge of what is a good compromise in a certain situation. Or we feel that we know of a good compromise, but not sure on how to achieve it. We just doesn't have enough knowledge in that area when it comes to that problem.
Sometimes in that past I came to that feeling. Not just with OO, with everything. My solution is rather simple. Do away with what you can afford.
Imagine you are starting up a company. Having worked somewhere else before, you know for the business you are in, to get the best results you need the best help you can get. Probably something like a VP of Marketing and a hordes of top notch highly paid engineer in your office campus.
Still, if you can't afford all that, there is no way to plan your business expecting all that to be ready to you. You just have to start with what you have. Its not going to be perfect, but its going to be a step in the right direction. And that's what matters.
Have a look at Smalltalk. Its the most pure object oriented language. It only has the concept of objects and messages and only 5 keywords to remember.
There are free implementations for all major platforms available, like Squeak (www.squeak.org) and Pharo (www.pharo-project.org) or you can use commercial ones (like Cincom Smalltalk, VisualAge, ...)
There are also free books available
http://stephane.ducasse.free.fr/FreeBooks.html
Have a look at the "heretic" Seaside web framework implemented in Smalltalk (http://www.seaside.st). Its cool since you dont have to take care of session data - just program naturally your workflow. We switched two of our applications from ColdFusion to Seaside (after trouble with CF components) and I hope we can migrate more in the future.
Seaside powers cool Web2.0 applications like dabbledb.com or auctomatic.com and has support for scriptaculous, jquery, you name it. The webserver is built in and we use Apache at the front to balance and scale.
But beware - Smalltalk (and Seaside) is completely different from anything you may have known before. You do not use your text editor and a compiler - it always comes with the full IDE and code lives in an image. But there are tools to share code and work in team (Monticello with squeaksource.com).
The only thing I miss compared to CF is the easy persistence - in Smalltalk you have more options and frameworks - makes it more complicated than direct access from scripts to tables (but also more cleaner)
Since my response was so long, I decided to post it on my blog: http://www.halhelms.com/blog/index.cfm/2009/4/2/Thoughts-on-Object-Oriented-Purity
Nobody gets it perfect in OO, no more so than imperative programmers produce perfect functional decompositions. I think about OO as an enhancement of abstract data types (a Pascal/Ada concept) to provide for polymorphic types.
I sympathize that all the theory you've read leaves you without a trust in your intuition as to what is the "right" thing to do. One way to develop that intuition is to read lots of good object-oriented code and study complex object-oriented APIs. It's like learning languages -- people learn to write good English not (only) by ready books about how to write well, but mainly be reading other people's well-written literature. A child learns to hear and understand before he learns to speak.
If you were programming in Java, I would advise you to read books on the Swing GUI tool set and also the utilities library. I don't know what is available in Cold Fusion, though. You might consider developing a reading knowledge of Java just for the sake of reading good programs to develop a sense of how to use OO.
@Frank,
I've heard that the Swing UI library is actually a horrible example of a library due to it's extreme level of abstraction. Maybe I am getting that confused with something else?
Don't be discouraged, your realization is actually a step in the right direction. OOP is a tool with many pieces and moving parts. You may or may not need all of them to do what you need to do.