|
Comments
|
Today's Top SOA Links
BF on CF Maybe We Should Try a Separation
Maybe We Should Try a Separation
By: Ben Forta
Oct. 4, 2002 12:00 AM
I have been writing and talking about ColdFusion components since before ColdFusion MX shipped. After I explained them in detail in two recent columns (CFDJ, Vol. 4, issues 6, 7), quite a few of you asked for practical examples of when and where they should be used. So, once again, let's take a look at CFCs, but this time from a very different angle.
Spot the Problem
<!--- Get users ---> So what's wrong with it? Don't see it? Look again. Carefully. Still nothing? Well, maybe there's nothing actually wrong with the code. It will run as is and will work (generating the appropriate output). But while it's syntactically correct, there actually is something very wrong with it.
<CFQUERY> Proliferation
Question: How many <CF QUERY> tags does your code contain? You can guess if you like (although I'm sure your guess will be lower than the actual total). Next question: How many of the SELECT statements in your various <CFQUERY> tags are similar (or even the same)? You'll likely find that most of your queries interact with the same set of tables. Maybe one retrieves fewer or more columns than another, or sorts results differently, or just passes different WHERE clauses, but beyond that, how many are totally different? Now for the most important question: What would happen to your code if a database column were renamed? Even more exciting, what would happen if a database schema were updated (as they should be periodically) so that your tables were split into multiple relational tables? Or - and I've saved the best for last - what if the database were changed altogether, maybe switching from one DBMS to another, or moving to an LDAP directory or an XML data store? What would that do to your code? Think it doesn't happen? It does, and when it does, rewriting client code can be painful. And often the changes aren't made, even though they should be, out of fear of the work involved. So improvement and progress are stymied by codephobia (I made that word up as the English language didn't seem to contain one as eloquent. Feel free to use it yourself). The problem is that the very nature of the Web and Web pages, combined with the immediacy of the platform, encourages this type of development (and, I should add, not just in ColdFusion). Chances are, you've written pages that include everything from database queries, HTML output, form validation, all sorts of conditional processing, and business rules, to logic and...you get the idea.
And that's what's wrong with the code I showed you previously:
For that matter...
Now, once again, think about the app you just finished or the one you're working on. What if there weren't a single <CFQUERY> em-bedded in the pages that generated output and performed user interaction, would that make your development life easier?
Separation of Presentation and Content
1. The back end (starting with databases)
The truth is, the front end should never be tied to any particular database. Each should be free to be improved on (and changed and adapted) without fear of things breaking. Similarly, you'd never want your business logic in the same page that generates HTML output. Why? Well, as soon as you need an alternate output format (whether it be Flash, XML, a Web service, or even a simple spreadsheet), you'll need to re-create all that logic (or patch your original file). So, back to our example: the code both retrieved data from a table and formatted it for output. What if I needed an alternate output format? I'd have two choices. Either I'd create a second file (copying the query code) or I'd put a big <CFIF> statement around the output so it could generate both output formats. While that may be acceptable (and even manageable) for simple code like this, imagine if the query were extremely complex and required all sorts of postprocessing. Then neither option would be really workable. What I'd really want to do is move the database-specific code out of the file that generates presentation into its own file. Then I could have two different presentation files (one for each output format) and have them use the same query by accessing the query file. In tiered development, content and its presentation are explicitly separated, making each more manageable, more usable, and more reusable.
ColdFusion and Tiered Code
It's been possible to write code like this in ColdFusion for a long time. Between <CFINCLUDE> and custom tags, writing tiered code has been doable. But neither option is ideal. <CFINCLUDE> is ill suited for highly dynamic content (for starters, there's no way to pass variables to an included page or to return results), and custom tags are too cumbersome (no built-in parameter validation, single entry point, can't be introspected and thus can't be shared simply, can't return results, and more). Which brings us to ColdFusion components. CFCs are designed for just this purpose, building tiered applications. Imagine that you could take all your user-related queries and store them in a single file, then all your product queries and store them in another file, and so on. Then, to obtain a list of users you could do something like this:
<!--- Get user list ---> This code calls a method (a function) named List in a component named user and returns a result named users. What is in the user component? It doesn't matter. Whatever it is will be executed and a result will be returned. Another way to invoke the component would be:
<!--- Get user ---> Here the user component is loaded as an object, and a specific method in that object is then invoked - in this example, passing a user ID and obtaining the e-mail address for the specified user. In both examples the component is now that middle tier - your presentation code talks to the component, and the component talks to the database. All that's needed then is the component itself.
CFCs as the Middle Tier
Look at this code:
<!--- User component ---> This is a complete (albeit rather simple) component. It defines a single method named List (the method used in the prior code snippets). List takes no parameters and returns a query (the same query as used above). The preceding code would be saved as user.cfc and references to a user component would access this CFC file. Here's the GetEMail method:
<!--- Get e-mail address method ---> This code would be placed into the same user.cfc file (all methods go between the <CFCOMPONENT> and </CFCOMPONENT> tags). It takes a user ID as an argument and returns the e-mail address for the specified user.
This is just the start of it. With all database queries in one isolated location, you can start getting creative. You could:
And it gets better. Dreamweaver MX is CFC aware and can automatically display a tree control listing all CFCs on your ColdFusion server. This allows users to right-click on any CFC or method to see more information about it, and even drag a method into their code to autogenerate the re-quired invocation code. All automatically, and all without having to register anything in Dreamweaver itself. Note: There's another benefit here, Flash MX integration. But more on that next month.
What Next?
Databases and database access is a good starting point. After all, it's what we do mostly with ColdFusion and CFML. But it's just a starting point. Any integration with back-end systems should be tiered, starting with databases but also including:
The basic rule is this: if it isn't tied to client code, then it doesn't belong in client-generation code. Simple as that.
Summary
Reader Feedback: Page 1 of 1
Your Feedback
Subscribe to the World's Most Powerful Newsletters
Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
|
SYS-CON Featured Whitepapers
Most Read This Week |
||||||||||||||||||||||||||||||