http://www.perlmonks.org?node_id=50638


in reply to Extreme programming... in perl?

(More info on Extreme Programming (the "other" XP) can be found on the original Wiki. There you'll find some early material from XP's originators, plus some interesting back and forth from the patterns community.)

Over the past year I've borrowed a few practices from Extreme Programming for my own (mostly solo) Perl projects, with mostly positive results. The practices I've adopted are:

In XP, a "story" is somewhat similar to a "use case". It describes a chunk of functionality in the system, how an agent invokes it, and what results. Implementing a story typically involves designing and implementing a bit of each layer of the system. It's sort of top-down, but taken in thin slices. The trick is to only design and implement what you need for the story, avoiding the tempation to overdesign or overbuild.

Writing tests cases first has a couple of benefits. First is that the test cases actually get done! My experience has almost always been that leaving test cases until the end means that they get squeezed out of the schedule, or overlooked in the mad rush forward. The second benefit is subtle: to write a test case you need to think about the objects you'll be testing, how they'll behave and interact, and how you can verify that they've behaving and interacting correctly. This is a very grounded approach. By approaching class design this way, rather than in some fanciful imaginative vacuum, you get testable classes, and method signatures that make sense to at least one client (the test case code).

Next up comes implementation. "Do the simplest thing that can possibly work" says just that. Defer complexity until you actually discover (in some future story) that you need it, and do something simple (and correct) to implement the story in user story in front of you. If you're modifying existing classes, do the simplest correct thing you can think of to effect the modification. (Here's where having a body of test cases that cover prior stories really pays off. If you broke something, you get to find out right away, while it's still fresh in your head.)

Refactoring means cleaning up the code. It's kind of like cleaning up the kitchen after cooking. Better to do it right away, so that you can start with a clean environment the next morning. More correctly, "refactoring" refers to a set of transformations you can do on code that maintain correctness. Discovering that you're performing the same operation in two different subroutines, and then extracting the operation into a new subroutine is one refactoring. (See Martin Fowler's excellent book "Refactoring: Improving the Design of Existing Code" for more info.) Here's where I force myself to find and resolve any #FIXME comments left in the code, and have second thoughts about using some neat-but-obscure trick picked up from PerlMonks.

I've been using these practices for about a year now. The biggest problem I've had is fighting off the continual temptation to design ahead. On reflection, I have to admit that much of design ahead work I've done in years past has been wasted "premature generalization." I'd have been better off saving the code and investing that time elsewhere. But it is still soooo tempting to design reusable packages in my head before coding the parts that I actually need now.

Along the way I built a simple yet quite effective test harness (applying the "do the simplest thing that could possibly work" dictum). It needs a bit of work to get it up to PerlMonks standards before I'll post it.

And sometimes I take my Extreme Programming hat off for a round of Perl Golf.