Thursday, June 24, 2004

Frameworks: The Good, Bad and the Ugly

D.Ross.Blog: Frameworks, Methodologies

Let's get this conversation out in the open.

Let's take some quotes from my infamous comments...

"That's my point, I am sure it is a good methodology, and I am all for improving our standards of coding to make ColdFusion is the solution for the web applications.

However, no methodology should sacrifice core values of performance and usability.

I understand for example, how it helps to have a common methodology for a team.

I am not here because I like slamming methodologies, I just want to make sure we are choosing methodologies for the right reason.

Because no matter how a methodology improves our coding standards/skills, it doesn't matter as long as it's coded to be the most efficient in performance and usable to the clients."

My point is that several-fold:

1. We should not just jump to a framework because everyone else does, or because it's a trend or fad. It must be because it fulfills the needs we have as a team/coder and because it delivers on our core values.

2. I don't care if it's the most elegant framework in the world, but if it takes away from the core values, then it's really not yet a good framework.

Here are my core values, and I hope they are similar to yours:

1. Performance and Scalibility: As my web apps get used by more and more people, I have to make sure that the web app is built for handling that, by using the most EFFICIENT/FASTEST LOADING ways of delivering functionality/content or whatever.

2. Url Usability: It sounds trivial, but it's actually a very important subtle thing. People like to be able to bookmark, or understand what page they are at. The old fusebox method of having all apps be on one page with different url variables, just doesn't cut it. Especially in the day of trying to do search engine optimization.

I do know it can do the seo friendly urls, but it should be on seperate pages. Which can be fusebox if you like that just includes the fusebox code. But we need to go a products page or a shopping cart page. There needs to be a visible difference in the address bar between pages.

3. The framework should be built to be easy to understand for people who don't even use that framework.

Point-in-case, at work we have several fusebox apps, that we don't even bother trying to fix because it's so convoluted trying to find where the actual code is and what not.

Now, I do approve of frameworks, as long as they are done right.

Of course it is much better than going blindly with no standards or no framework....

But we have to evaluate what is a good framework and what is a bad framework.

There are plenty of innovations that fusebox and other frameworks have brough to the cf world, that I like.

Like the idea of wireframing your apps, I still want to play with that as a great way of planning out your app logic.

I have not yet played with mach-ii. I am honestly a late adapter, probably always will be.

And maybe I still think that a good web app, is 1-3 pages with 5-10 cfincludes...

And because my code is commented, indented, planned, easy to read and understand, then I don't have to worry about dying, and having someone try to figure out what the heck my code is trying to do.

Unless coldfusion has changed so much that the speed differences are a lot different than they used to be, then I'll be glad to change my mind.

As long as the reuse method is the most EFFICIENT/RELIABLE way.

And as a nice as cfc's are, they are not it, nor are cfmodules or cffunctions or cfscripts.

CFINCLUDES are still the fastest gun in the REUSE West...



23 comments:

  1. Anonymous11:40 AM

    Craig, all I have to say is that you need to actually build an Enterprise application and you will realize that you are wrong on many, many points.

    I like the idea of your blog but I do not like someone that doesn't have experience at building Enterprise applications to preach to people that a cfinclude is sufficient enough for code re-use.

    Bryan F. Hogan
    http://www.cfm-applications.com/

    ReplyDelete
  2. Anonymous12:53 PM

    I agree somewhat with Brian.

    Then another point to consider is that, while cfinclude is nice, it's not the end-all to everything. It's not the best tool for every job. It's not something that breeds clean code re-use. They're good for page headers and footers, but after that, they start to get ugly. I wouln't use an include for a string formatting job, a function would do much better. I wouldn't use a cfinclude for complex data abstraction, a CFC is much better suited. I wouldn't use a cfinclude for highly-reusable page formatting, a custom tag is much smarter.

    Another thing is that cfincludes are not even as fast as, say, a CFC. Once a CFC is loaded in memory, you no longer lose the performance hit of an include. Load it in your application and you only do it once a month instead of once per request. Now you start to see the performance increase.

    Pick the best tool for the job. That's all there is.

    -nathan strutz
    http://www.dopefly.com/

    ReplyDelete
  3. Anonymous1:19 PM

    I have to disagree, though I can agree with your possibly limited perspective. Limiting yourself to cfinclude works fine for quickie projects, but the larger and more complex the application the more they can hurt than help. The project I am involved in has been liberated by CFCs. Simple includes assume way too much about the context of their use to provide efficient reuse.

    Erik M

    ReplyDelete
  4. Anonymous2:01 PM

    I completely agree with the last comment - CFincludes are good for some instances like drawing common headers and footers (that NEVER or RARELY need a variable passed in/out of them), but for true modular code, CFCs, or even libraries of UDFs are better. You can CFinclude a template that's nothing more than a collection of UDFs and re use the code anywhere in the template, context not required. It's the same speed as a CFinclude too.

    Nolan

    ReplyDelete
  5. Anonymous2:08 PM

    Craig,

    I suggest you read this article about encapsulation:
    http://www.libertyassociates.com/pages/column2.htm

    It's targeted towards C/C++ developers, but it's the concepts, not the coding examples and syntax, that are important. Hopefully, after understanding those concepts a little better, you can better appreciate the paradigms underlying the frameworks and methodologies you mention, and maybe even view your own development efforts in the context of these paradigms.

    I sense that all of your experience has been in a one-person development environment and with relatively small or simple projects. Things are very different with large, complex systems or when you're working in the context of a larger team (and I'm certain anyone who has worked in such circumstances will agree). I'm sure the "core values" you refer to work wonderfully given the context of the project. In a different context, though, namely a more complex project or a larger development team, the "core values" you name become an oversimplification as other issues (including coordination of development, maintenance of complex functions, implementation of enhancements on already complex systems, etc) become more prominent. While it's possible to mitigate these issues using a combination of cfincludes, strict development standards, and verbose commenting, you'll find one of the primary purposes of cfmodules, cfcs, fusebox, mach-ii, or any similar feature/framework is to facilitate, and better yet, *automatically enforce* coding practices that help avoid these issues.

    -Doug Keen

    ReplyDelete
  6. Anonymous2:11 PM

    "This blog is about those who dedicate themselves to the perfecting their craft, and have become purists in the standards they have established."

    The above makes no sense whatsoever. But anyway, on to the question at hand.

    "1. We should not just jump to a framework because everyone else does, or because it's a trend or fad. It must be because it fulfills the needs we have as a team/coder and because it delivers on our core values."

    I doubt anyone will disagree with you in regard to picking a framework based on a trend or fad. However, a frameworks' job is not deliver core values. A framework should provide useful abstractions for a chosen architecture and/or pattern.

    "2. I don't care if it's the most elegant framework in the world, but if it takes away from the core values, then it's really not yet a good framework."

    Again, a framework has nothing to do with core values; it has everything to do with assisting in the implementation of an architecture and/or pattern.

    "Performance and Scalibility: As my web apps get used by more and more people, I have to make sure that the web app is built for handling that, by using the most EFFICIENT/FASTEST LOADING ways of delivering functionality/content or whatever."

    If the above is any implication of your technique then I suggest you invest in a load assessment tool and learn the truth; performance and scalability have less to do with each other than you think. You'll find that it is just as common to have pages that load in 10ms with a single request load in 10s with thousands of requests and the corollary that pages that load in 100ms with a single request continue to load in 100ms with thousands of requests.

    "Url Usability: It sounds trivial, but it's actually a very important subtle thing. People like to be able to bookmark, or understand what page they are at. The old fusebox method of having all apps be on one page with different url variables, just doesn't cut it. Especially in the day of trying to do search engine optimization."

    I haven't seen a framework that forces URLs to be in a certain form. Sure they may only provide a built-in way of handling URLs of a certain form, but that doesn't mean you are stuck.

    "The framework should be built to be easy to understand for people who don't even use that framework."

    Possibly, it depends on the understanding of the developers involved. One of the reasons design patterns are so popular is that different implementations can claim to follow a certain pattern allowing developers with no knowledge of said implementation to understand at a high level what is going on.

    "CFINCLUDES are still the fastest gun in the REUSE West..."

    Having lead a team that likely implemented one of the largest and most complex CFML applications that used cfincludes for reuse I can tell you for a fact that you are out-of-date. We built the application with cfincludes because of the performance limitations of other methods. Of course we had to put in place serious workarounds since out use of cfincludes wasn't intended. All of that is no longer needed since CFCs provide the language construct for reuse in an efficient way. They have their problems, but the problems are easier to deal with than cfincludes.

    -Matt (mliotta "at" r337 "dot" com)

    ReplyDelete
  7. Anonymous2:11 PM

    You also seem to be missing the key point that everything in development is a tradeoff. If you REALLY place performance above everything else, why not code in assembler?

    The reality is that for each level of abstraction you put in place, you pay for it with a drop in performance. Every CFINCLUDE decreases performance. Every CFMODULE decreases performance. Every call to a CFC method decreases performance. Using a framework decreases performance.

    However, with each of these costs there are benefits: easier maintenance, encapsulation, better testability, standardization (especially with CFCs and frameworks). I would argue that performance is one of the LEAST important aspects of the ususal web application. As long as it performs acceptably under normal conditions, I'll take that in exchange for vastly improved maintenance and testing. If the app starts to run slowly, add more hardware. Adding a GOOD server costs a few thousand dollars at most. This cost is FAR less than the cost of a developer (or a team of developers) trying to maintain a poorly designed system.

    I'm not saying it's ok to write slow code, I'm saying that it's silly to write fast code at the expense of everything else. There's an acceptable middle ground.

    - Brian Kotek

    ReplyDelete
  8. Anonymous2:27 PM

    You're too concerned with performance on a micro-level. Sure, any framework introduces an overhead but the trade off is code that is *much* easier to maintain and enhance and, after all, people cost more than processors (another way of acknowledging that something like 70-80% of the cost of any piece of software is in the maintenance of it). Raw performance is *not* the be-all and end-all.

    Frameworks are successful only if they provide benefits to developers without placing too much of an overhead on the application. Fusebox is as successful amongst ColdFusion developers as Struts is amongst Java developers (which is quite an achievement and a testament to the value many developers get from Fusebox).

    Of course, you can still write bad code using a framework - they are not silver bullets. Good frameworks help developers create more modular, more maintainable code and help them build it quicker than would happen without a framework. Of course, for apps with just "1-3 pages", a framework would probably be overkill but I think most CFers build far more complicated apps than that - and, it should be noted, the vast majority of CFers don't use a framework (probably over 90% - just as in Java and every other programming language for which frameworks exist).

    As for cfinclude being the "fastest gun"... well, others have pointed out that CF provides faster (higher performance) ways to reuse code and there are certainly better structured and more robust ways to reuse code. But then maybe your reference to "fastest gun in the ... West" is really about cowboy coders?

    Sean A Corfield
    http://www.corfield.org/blog/

    ReplyDelete
  9. Maybe my drive for performance, is having to always clean up after other people's code.

    Who don't code for performance, do select *, all the things that inhibit scalibility.

    Things change as of course they do, over time.

    Just because I do not agree with you, that somehow makes my point of view, limited?

    ReplyDelete
  10. Anonymous3:18 PM

    Performance has nothing to do with cleaning up code.

    SELECT * is a poor example but oft-quoted. Generic code probably should do SELECT * if the query is passed off to other code to handle - that means you don't have to change both the query and the code that uses the query if you change the DB schema. Again, it's all about trade offs.

    ReplyDelete
  11. Anonymous3:27 PM

    Craig: "But we need to go a products page or a shopping cart page."

    If you want a certain look to a URI, then you use mod_rewrite or ISAPI_rewrite to get it... you don't restructure your app's code to produce a desired side-effect in your URIs.

    --
    Roger Benningfield

    ReplyDelete
  12. Anonymous3:44 PM

    Here's what I'm really confused about. It seems like your argument is:
    1) Formal methodologies aren't for me.
    2) Methodologies should be selected for their usefulness, ie pick the right tool for the job.
    3) Here is my personal methodology
    4) No application should ever sacrifice performance.
    5) My personal methodology holds performance as its key value.
    Thus: My personal methodology is always the right tool for the job.

    While I do agree that you should aways choose the right tool and the right method for the job, it doesn't seem that you actually practice that. You aren't chosing a methodology based on the functionality of the application or even on the client's needs. You are using the same methodology for all jobs and retroactively claiming it to be the correct methodology for the job.

    While your agrument has many, many incorrect assumptions, some of which have been mentioned already, it is the lack of internal consistency in your argument that bothers me the most.

    Jennifer

    ReplyDelete
  13. Anonymous4:27 PM

    Hi Craig, forgot to post this earlier. I'm sure you will find this link interesting.

    http://hillside.net/mission.html

    ReplyDelete
  14. Anonymous4:30 PM

    Of all of the blogs which are posted on FullAsAGoog, the only one I really loathe is this one. If there was some manageable way to filter out this blog in the FullAsAGoog RSS, I would. I really hope no one out there is taking any of your advice.

    You have a very narrow view of the world, and yet somehow have it in your head that you preach the truth. Instead, you have "performance" in mind at such as miniscule level it proves your naivety and inexperience with large scale software development. Most people tend to uses actual facts and data points to draw conclusions rather than emotion-- you should check into that.

    I concur with Brian-- you really need to get some Enterprise level experience as well as a roundtrip ticket for the cluetrain before speaking out so much about topics which you only mildly grasp, including taking other people's comments completely out of context (I.E., your silly rant about Ben Forta saying CF was not an e-commerece platform).

    ReplyDelete
  15. Anonymous4:49 PM

    Craig,
    I am so glad you were not there when science was giving birth to technology. You would have just pushed it back inside.
    Everything has to function under some solid Framework. You should never prefer speed over quality. Just think about it and stop being so annoyingly different.

    ReplyDelete
  16. Anonymous5:57 PM

    learn, to use, a comment, correctly. Thank you.

    ReplyDelete
  17. Anonymous5:58 PM

    I meant, to use, a comma, not, a, comment.

    ReplyDelete
  18. Anonymous5:18 AM

    Craig, you mentioned in a previous post that frameworks, such as Mach-II, are hard and that your brain doesn't work like that. I think the same is initially true for most people, but what I would recommend is that you put your skepticism aside, set yourself the challenge to write something simple using a framework and *force* yourself to learn the concepts first-hand.

    Take your time, read the documentation/forums and then re-factor, re-factor, re-factor until you've got a good handle on the best practices. Yes, it may seem long-winded and overly-fussy at first, but hopefully some of the benefits will become more apparent as you learn more.

    I've actually found it quite fun to start from scratch and try something new. Give it a go!

    ReplyDelete
  19. Don't worry Craig. I happen to agree with you. I've been designing sites for a very long time. Recently, I got lumped with a legacy Mach-II app on a very large project. It didn't jell very well with my way of thinking, resulting in a very steep learning curve. I also felt that the code was sluggish but assumed Coldfusion itself was to blame.

    Finally I went through the code and discovered that the Mach-II framework consumed between 3 to 5 SECONDS ON EVERY PAGE! and it's URL structure caused Google to bypass much of the site. It's XML config file is difficult to read and inflexible. Mine was over 5000 lines - most of it XML markup.

    I still don't know excactly why Mach-II is so slow but rewritting the site using CFINCLUDES and cached CFCs reduced the page code time from 3000-5000 ms to a mere 6 ms and I still have all the benefits of a clean MVC layout and SES urls.

    The moral is - don't trust experts - Especially those promoting Mach-II as though it's the second coming of Jesus. Experiment with competing frameworks and use your own judgement. Just comment your code clearly and use UDF's and CFCs well.

    ReplyDelete
  20. Spliff - I think that your performance problems were mostly self-induced. I would be willing to bet that you had debugging turned on which is a big no-no with Mach-II. As for not using a framework such as Mach-II or MG or FB for an application because you think it's too small, I would suggest casting your mind back to all the projects you've had where the client says "It only does this ONE THING! I don't need all this other stuff!" and then two weeks later they say "Gee, it sure would be nice if it did 'x' thing..." and so on and so forth until finally you have hundreds of pages and a sprawling plethora of code. Using a framework from the beginning ensures that by the time you've gotten to that point, if you've used best-practices along the way, then you don't say to the client "This thing is a teetering pile of crap and we need to re-architect it". I guess the moral to the story is 'Choose a framework THAT WORKS FOR YOU. Learn it inside and out. Use it in ALL projects."

    ReplyDelete
  21. Anonymous2:51 PM

    Those are good points. We have to separate what is to develop a framework to prove a point vs building an application.

    A framework, depending the circumstances, will be limiting for some organizations. And in many cases it depends where you want to put your time, in your application logic or beefing up a resume.

    Some frameworks are seriously... overkill.

    ReplyDelete
  22. Anonymous2:37 PM

    Have to disagree with you. Cfinclude is one of the worst tags in the language. With Cfinclude, you don't know what variables are being polluted into your scope, so adding/removing a variable in the parent or child template will likely break something. You don't know what variables being passed or returned, so adding/removing a variable to the parent or child template will likely break something. When something does break (and it will using cfincludes) a bug in CF's error handling will only show you the top-level template, so you won't even know where the error occurred. Throw in a programmer who thinks CFCs are silly and 12-levels of nested cfincludes is cool and you get an unmaintainable nightmare.

    ReplyDelete
  23. Like any tool cfincludes can be miss used.

    The key really is how to structure the application, so as to best provide functional/navigational needs.

    Mostly for my includes, i have navigation includes, and content includes.

    100% of them i don't need to send/recieve any information from an include.

    I don't think CFC's are evil, but has to be used with common sense.

    ReplyDelete