Thursday, August 18, 2011

Sipping (Systemically Incremental Programming)

Sipping is based on the idea that a journey of a thousand miles begins with a single step.  Assuming that you're walking, you must take a first step, and that step will not be a 19 yard leap.  The only real question is what direction that step will take.  To determine this, one locates the destination and begins to walk.


Each step we take is about the same length as the previous step.  Our speed will remain relatively constant.  The only question that will be asked over, and over again with each step is - what direction will I walk next.  If I get to a stream, and there are stones to walk across the stream, I might (from time to time) need to choose between one stone or another as my next step.  Occasionally I might need to actually jump (a bigger step than most of the others), but in general - I walk.  Step, by step, by step.

"SIPPING" takes any development problem, of any size or complexity, and attempts to break it down into a series of bite sized SIPs.  The process of creating an application of 1000 features, begins with a single SIP, and is completed SIP, by SIP, by SIP.  



Definitions
Sipping (the system)
Systemically Incremental Programming

SIP (noun):
A highly cohesive unit of work that follows the rules described below.


To SIP (verb):
To develop new functionality (of any size/complexity) by breaking the problem down into small sips (see noun).


The Claim
Sipping is an approach to development that attempts to break down any problem, of any level of sophistication/complexity, into SIP sized units of work.  By doing so, you will (hopefully) see one or more of the following benefits.  When compared with the traditional way that code is written, your code will be:
  • Simpler and more elegant, start to finish
  • More stable and bug free, out of the gates
  • Easier to read
  • Easier to change as conditions require
  • Easier to maintain by you (or others)
  • Better software at the end of the day for the end user

    and last, but not least

  • Much, much faster to produce in the first place
What is a SIP?

A SIP is a highly cohesive unit of programming work that follows these rules, whenever possible: 
  • A sip is an incremental, highly cohesive improvement to a new (or existing) system
  • A sip solves one, and only one problem
  • A sip leaves the system that it modifies better than it left it
  • A sip is 100% backwards compatible
  • A sip is designed, written, tested and committed back to the version control database as one, atomic step

How it Works
Commonly accepted in an Agile environment would be to take a 1 year project, and break that down into 6 smaller, 2 month "sprints".

To begin with, using SIP, each 2 month sprint should be further broken down into as many, small, atomic bugs/features as possible.  Each bug should (whenever possible), be 10 hours in length or less (estimated).  If a bug is larger than 10 hours, it can probably be broken down into 2 or more smaller bugs.  

In the scenario under consideration, we have a 1 year project, being completed by a team of 5 developers.  Each "sprint" is a 2 month duration with 4-5 weeks of development, 1-2 weeks of testing, 1-2 weeks of polish before moving onto the next sprint.  With 5 developers, I might assign 100-125 hours of bugs to each developer for a total of between 500-750 hours of development scheduled in the sprint.  With an average bug size of 5 hours, this would be about 20-30 bugs per developer.

Let's look at the experience of too different developers now.  I'll call the first one Frank and Frank has never heard of "sipping".  I'll call our "sipping" developer Joe.  


They each pick a 5 hour bug.  The two descriptions below are consciously hyperbolic.  I am using these two developers as archetypes;  that being said, the kinds of problems (and benefits) that they will each see are, I think, real.


Franks Approach
Frank looks at his bug, comes up with a plan.  It's only a 5 hour bug and he's pretty sure he knows what he's going to need.  There are 4 different classes that need to be created, and he starts by creating stubs for each of the classes.  Then he starts adding methods, properties and UI elements to consumes the classes.  15 hours into the bug, he's got spaghetti code, and only 1/2 the functionality requested by the bug is actually working.  In addition, he's got a list of five additional "issues" with his code, that still need to be resolved.  
Further, each time he adds a new piece of functionality to one of the classes, the whole problem get's more complicated, and, exponentially he digs himself further and further into a hole.


Joe's Approach
Joe's "sipping" approach is different.  Joe starts by looking at his 5 hour bug and splits it up into 5 small "sips".  Each sip meets the criteria listed under "What is a SIP?".  Each of Joe's SIPs also involves creating some classes and maybe some UI elements, but he has found a way to decouple the 5 major elements of the bug, from each other, into separate SIPs.  

After completing the first SIP, he has only added 2 new classes, and no UI elements.  These two new classes are totally functional, they add 2 new "features" to the code base, that will be used in SIPs 2-5.  He has tested these classes, made a few improvements that he hadn't originally thought of (which make the classes more stable/complete).  All is well.  After fully testing, Joe checks in his code, having incrementally improved the entire system.


Now Joe re-evaluates the remaining 4 SIPs that he had defined.  Some of the benefits that he will have at this point include:

  • Most of the time, the remaining SIPs will, as a group, constitute a simpler problem to solve than the original 5.
  • He will probably see the remaining SIPs with more clarity than he did before completing SIP 1
  • In many cases, he will be able to simplify the design of one or more of the remaining SIPs in the bug, based on the good work done when completing the first SIP.
Now, Joe rinses and repeats.  In other words, he picks the next most logical SIP and gets to work.  At the end of 3.5 hours, Joe has completed 4 of the original 5 SIPs, and, during this process, realized that what he thought was a separate SIP (SIP 5), was actually taken care of by the work done earlier, and he's done.  

At no point during this process did Joe have more than 1 (or maybe 2) moving parts to be working with.  Each step (SIP) was simple, easily defined, easily verified/tested, and easily understood.  The complexity that resulted from the complete implementation was the interaction of the 5 SIPs together to create some cool new feature (or set of features), just as the complexity of an entire, enterprise level application comes from the collection of multiple developers, each completing hundreds (or thousands) of bugs over many years - not one developer writing 1,000,000 lines of bug free code in an afternoon.

The journey of 1000 miles begins with a single step.  For some reason, developers see a new feature, 200 hundred yards ahead of them, and think that they can just leap to the finish line.  Unfortunately it doesn't work that way, and the result of trying, is that they fall down and break most of their bones along the way!


    1 comment: