Back in the late-1990s, the Internet Service Provider where Simon C. worked was a mere micro-sized version of what they are today. Their website's original e-commerce system only needed to sell one thing — domain names, and a limited subset of them at that — so the shopping basket and invoicing parts of the system didn't need to be all that intelligent. They simply looped through each item ordered by the customer, displayed the description and prices of each one, and worked out the totals at the end. The whole process was so simple in fact that it made sense to the original developer to write the system so that the shopping cart and invoicing pages shared the same code.

Over time, the ISP grew in size to sell additional products such as new domain types and packages with a multitude of sub-products. Also, as the system grew in size, the site began running slower and slower. This gave Simon a reason to look into ways to improve the efficiency of the shopping basket and invoicing parts of the system.

However, the more familiar Simon got with the code, the harder it was for him to understand why it was allowed to remain in place for over ten years.

Elseif()s EVERYWHERE!

They say it takes an entire village to raise a child, but Simon discovered that it took over 16,000 lines of code to process the sale or print an invoice.

How could something like this be? The answer was surprisingly simple. As the company grew, it was simple to add new products. Just add a record to the master product table in the database and then add a new "elseif()" block to the shared code. Same thing went for discounts - toss in another elseif(). T-Shirts? Another elseif()...and so on so that the code was almost entirely made up of hundreds elseif blocks, each of which would need to be evaluated whenever a customer would add or remove an item from their shopping cart. Also, a side-effect of this design was that if someone wanted to change a product's description, for example, they couldn't just edit the database record, they would have to create a new product code and leave the old one in place forever.

Simon figured, My work's cut out for me - it should be easy to improve performance! Just trim out the elseif() blocks for the old items and discounts and I'm done! Ordinarily, Simon's reasoning would be absolutely correct, however, there was a small snag in this plan in the form of several hundred dire warnings.

¡NO TOCAR!

In looking for candidate code to trim, Simon found that most elseif() blocks heeded the warning DO NOT REMOVE and DON'T TOUCH UNDER PENALTY OF DEATH and the like, just like the following:

// xmas offer 20071206 - 20080103 DO NOT REMOVE, EVER!!
if($rowval['orderitemref'] > 10295755 &&  $rowval['orderitemref'] < 10373106 && (
    (substr($rowval['domainname'], -3, 3) == "com") ||
    (substr($rowval['domainname'], -3, 3) == "net") ||
    (substr($rowval['domainname'], -3, 3) == "org") ||
    (substr($rowval['domainname'], -3, 3) == "biz"))) {
       $thestr.='<font face="arial,verdana,helvetica" '
         .'size="-2" color="#ff0000"> at special offer price.'
	 .'<br>Renewal at standard price</font><br>';
}

The reason for this was also simple - as new items, price changes and special offers had come and gone over the years, it had exposed the problem of how the system handles historical invoicing. You see, the important thing about invoices is that they must be immutable. If a customer called up to argue a charge from six months ago, customer service had better be able to pull up that same invoice and it had better match what the customer saw at the time.

What Simon needed was a brilliant plan.

The Brilliant Plan

Simon figured he had two options in trying to bring down his goliath. The first option was to refactor the 16,000 lines into a system that would be able to regenerate ten years of invoices flawlessly and spend the rest of his life regression testing while in the meantime, the number of elseif() blocks would inevitably grow.

Alternatively, he could take the quick, dirty, and simple route: print out the historical invoices so that the CSRs could pull up when needed. Well, not print on real paper, but rather batches of PDFs of every historical invoice. This would allow him to simply ditch the old code entirely.

Simon was immensely proud of this solution and presented the idea to management. "Why would we want to change," his boss rhetorically asked, "what we have works already and has been working consistently for the past ten years!"

Defeated, Simon went back to his maintenance work and added yet another elseif() block to represent yet another promo offer.

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!