Re-Refactor
Posted at August 24, 2005 09:48 PM - Category: ASObill
I've been sick for the past few days and I'm finally snapping out of it. Luckily, with the line of work I'm in, as long as I get a decent enough amount of sleep, I'm still able to function (although, I probably don't look that good to other people). During this time, I've been working extensively on ASObill now that we have most of the kinks worked out with ASO's new VPS offerings.
The biggest thing I've been doing is refactoring the code to remove almost all the redundancies I've been building up into my code. The basic format of a request sent to ASObill used to be like this:
- Load up the appropriate module
- Have the module determine which method to run for the particular input passed to it.
- In the method, check the input to handle blank values (in case there is an error with a form submission and we're heading back to the form with the error).
- Do whatever awesomeness the function is designed to do.
- Print out the appropriate template.
It doesn't look that bad from a distance, but there's a lot of repetition for each module and between the methods of a module. I was re-doing the full input validation for every module and having to manage the template output, as well. What I've done to relieve most of this work is take some cues from Rails. Look at this basic bit of Ruby code from a very simple Rails app:
def list
class DemoController < ApplicationController
scaffold :recipe
def list
@recipes = Recipe.find_all
end
end
What's nice is you don't have to tell the application which method to call in the class, it takes that from the input automatically. There is also no need to define a template. Input does happen to be ignored in this example, but it's also handled very simply.
Now, here's a similar function from ASObill:
class Products extends Module
{
function showproducts()
{
$this->db->query( "SELECT * FROM ab_products" );
while( $p = $db->fetch_array() )
$this->out['products'][] = $p;
}
}
This is a slice of the code, not the full thing, but you get the point. Aside from my odd code formatting (Hey, I'm used to it!), it's exercising much of the same efficiency you get with Rails. You don't have to tell it which method to call, it's found via the parent Method class. That same parent class also figures out the right template to output. I'm using Smarty for templating, so the loop needed to print out each product is stored in the template itself.
As a result, I've cut the core module code by 40%! Quite a substantial gain. I've also simplified development because there's less scrolling through code and less complexity in the methods. I've got to expand the database mode to add some better functionality (such as findall()), similar to ActiveRecord. However the biggest thing is that it's gotten me feeling much better about the direction of the application. I've debated switching to Rails, just because of the buzz it's generated. But this method lets me get all the functionality and productivity with wide-spread support of PHP.








