Tuesday, November 10, 2015

Refactoring During Requirements Analysis

Refactoring is a process of reviewing computer code to look for improvements.  Generally these improvements identify redundancies and replace repeating code with modified general purpose (or specific purpose) code, relocate variables for easier maintenance, involve performance reviews and resulting tweaks, and so on.  Given a proper project life cycle, this should be an ongoing effort.  But there is a not-so-obvious time before the writing of the code even commences that the refactoring mind-set is highly applicable.

I'll use a recent case by way of illustration.  I spent the better part of last November through June writing code to handle the transformation of payroll data from one system, through an effective in-memory pivot table, out to another format and then uploading that resulting data to a remote webservice.  The rules for pivoting the data were different for almost every state.  In our case, I wound up creating a base class for the timesheet workflow and then subsequent subclasses to handle each specific location's special rules.  In all we identified three requisite subclasses to effectively handle every state in the US.

Getting to the point where I could clearly see the overlapping functionality for each workflow took some time.  We went through 9 iterations to finally get California's ruleset working correctly and wound up making changes to the superclass a few times along the way.  But before we even got to that, I started with a look at the customer supplied flow charts.  They were tweaked by the project manager / business analyst and then I had a go at them.  We worked back and forth with the business as I found logical black holes and contradictions and rules were decided as we went.  This "refactoring" of the paper flow chart provided an iteration phase during design that allowed us to have a pretty good, but  far from perfect, topographical view of the class structure that would result before I began writing the code.

Semantics being what they are, we discovered during testing that several terms suffered from the oft assumed incorrect perspective and definitions.  We thought we knew what the business was saying because they used terms that were common, but within the context of their business flow, some common terms had special meanings.   Had we refactored, or iterated with a view to refinement and correction, during the requirement gathering process as well as the design process, we might have caught those issues.  Some of them were pretty sneaky though.  But, that should be a cautionary tale to always include an insanely detailed glossary of terms.

So, next time you're faced with a complex task, take it in several passes, make paper models like sketches and flow charts and really question your assumptions and dig into the details.  There's always pressure to rush into the act of producing, whether building, coding, or making drawings.  Resist the headlong rush, take the time to really understand the goals, and go over it again and again until you're sure you've got it.  Even then, you'll be refactoring later.  :-)