Sunday, December 11, 2011

Beating the Flying Spaghetti Code Monster with CFWheels - Part 2

Beating the Spaghetti Code Monster

Recap

As I mentioned in part 1 of this post, when I started writing web applications with ColdFusion I quickly amassed a large collection of autonomous files that would often break if I changed a variable or parameter that should be passed into the next. Adding or removing a column to a form / database table could take 25 minutes to update all of the SQL files. I had become enslaved to the “Flying Spaghetti Code Monster”, as I like to call it, and knew there was a better way and wanted to find it.

The Application

As I also mentioned in part 1, I had been re-hired to maintain and update a web application I wrote 7 years prior. This application had well over 350 individual files and the folder size was near 80MB. Although I had started to use the Fusebox framework, which helped start to organize my files, I didn’t follow-through on converting everything to Fusebox. This meant that my directory structure looked something like this
Spaghetti Code Directories

Conversion

As also mentioned in part 1 of this post that I decided to slowly convert the application to the Coldfusion on Wheels framework. I decided to do this cutting off one “tenticle” at a time, or one section/feature at a time.
First I identified a small section of the application that I could replace with the CFWheels framework. I selected one of the “system options” that allows users to add new values to a drop-down list of patient types. The code for this was located off the root of my application in a /system folder along 15 other similiar system options that were almost identifcal. I also needed a place to put my CFWheels core files.
I decided to put the CFWheels framework files in a directory named “hla”, which is the web application name as referred to by the staff, under the /system folder, so /system/hla/
CFWheels framework location
I setup my database connection info in the /conf/settings.cfm file so that my database connection would be the same as the spaghetti code portion. Next, I didn’t want to have two sets of Javascript, CSS or other asset files like images, so I had to modify my CFWheels layout.cfm file to reference the ones that the spaghetti code files were using.
layout.cfm
At this point I could browse to the CFWheels portion, by manually entering the URL, and receive the default CFWheels welcome page. I then added a new entry on my system options menu to point to the new CFWheels location where the system option I was going to convert would live.
At this point I created a model file, Patiettype.cfc, and in the init function I added code to specify my database table names that didn’t follow the Wheels convention, but were used by the Spaghetti Code application
<cfset table("tbl_authors")>
Next I followed with each database table column as a property, using the current database column name for the column attribute but a CFWheels convention name for the name attribute, as outlined in the CFWheels documentation.
<cfset property(name="firstName", column="tbl_auth_f_name")>
These system options required that I setup some associations, and this was a great place to learn about that as I’d need it for every other part of the application.
At this point I could follow the CFWheels conventions and develop the CRUD for the Patienttype just like I would a brand new CFWheels app. After I have the CRUD working for this system option, I’d then remove the link to the old files and leave just the new one. Then I’d have the users work with that section for about a week. Once we were sure everything worked correctly, I’d slowly remove the old files (that I now had in Git version control).
Using this same method I slowly worked through all of the 16 system options, as if cutting off one “tenticle” of the Spaghetti Monster at a time. After I finished with those small, simple CRUD actions, I moved onto more complicated sections. The whole Contacts portion, then Hospitals portion, etc.

Progress

I found the Coldfusion on Wheels framework in February 2011, then started implementing it in March 2011, working part-time and slowly through each of the tenticles I mentioned. If new features were requested, or something needed to be changed, I fought the urge to do a “quick and easy” one or two file solution and forced myself to do it the CFWheels way. At first this was challenging, but once I got use to it, the changes happened faster.
At this point, December 2011, I’ve removed at least 23 of these “tenticles” with two medium sized tenticles and one large tenticle left to remove from the monster. I’m excited to finish these sections off and sever the head of this monster once and for all. In hindsight I’m glad I started with smaller tenticles as it allowed me to learn CFWheels with smaller sections of code, but also to find “gotchas” early on.

Gotchas

One of the things I didn’t expect was the Spaghetti Monsters session scope being overwritten when I moved went to a CFWheels framework page. This made it a little tricky because I’d use the session scope to retain the currently logged in user ID and if they were a valid user or not (to prevent unauthorized access). After I’d leave a CFWheels page and go back to the Spaghetti Monster code I’d be kicked out of my application. My “fix” for this, at least for the time being, was to use client variables for the Spaghetti code portion of the application and session variables for the CFWheels portion of the application.
The next thing I ran into, since my session scope was being overwritten, was once I moved to a CFWheels portion of the application I’d didn’t have my session variable with the user ID from the Spaghetti Monster code. To fix this I added an obtuse URL variable on the menu links in the Spaghetti Monster code that CFWheels would then use to identify the user and create the session scope variables I wanted.

Summary

I feel converting this application to the CFWheels framework has helped with the following:
  1. Brought some sanity back to how this application is structured and maintained (huge benefit)
  2. Saved gobs of time not having to maintain query files with endless CFIF statements and cfqueryparam tags (CFWheels ORM does that all for me, huge benefit)
  3. Made the application run faster, I mean noticably faster to my users
  4. Decreased the code folder from 80MB to 33MB
  5. Allows me to add new features or make changes in less time then before because things break less when changes are made
  6. Allows anyone that knows about the MVC pattern to help or take over this application
  7. Made Coldfusion programming fun again (most important of course)
While converting this application from the Spaghetti code to the CFWheels framework from “the inside out” has been a slow process (because of my, not the framework), I don’t regret doing it at all for the reasons stated above. It’s been a great way to learn CFWheels and to work with the CFWheels community. At this point I can’t imagine developing Coldfusion applications without using the CFWheels framework.

No comments: