Agile versus “Flat-Footed” development

Monday, October 4, 2010

As I start work on my eighth Agile project, I felt it was time to take a breather and recap everything that I have learnt about Agile (the fact that this post just has 2 points to touch upon doesn’t speak wonders for my learning ability…however, living by the maxim that quality trumps quantity, I shall proceed…)

The whole idea behind Agile is based on the assumption that all customers are ‘fickle’ (for lack of a better word).  This means that all requirements are subject to change (even the ones that are ‘locked down’). Not only can a customer change their mind (about anything) later, but the software must be tweaked/revamped as needed to accommodate the changed requirements.  I remember a poster from college about ‘Rules that Women would like to share with men’…

The Rules

  1.  
    1. The Woman always makes the Rules.
    2. The Rules are subject to change at any time without prior notification.
    3. No Man can possibly know all the Rules.
    4. If the Woman suspects the Man knows all the Rules, she must immediately change some or all of the Rules.
    5. The Woman is never wrong.
    6. The Woman can change her mind at any given point in time.
    7. The Man must never change his mind without express written consent from the Woman.
    8. The Woman has every right to be angry or upset at any time.
    9. The Man must remain calm at all times, unless the Woman wants him to be angry or upset.

Substituting ‘Customer’ for ‘Woman’ and ‘Developer’ for ‘Man’, here are the rules as applied to software development.

The Rules as applied to Software Development

  1. The Customer always makes the Rules.
  2. The Rules are subject to change at any time without prior notification.
  3. No Developer can possibly know all the Rules.
  4. If the Customer suspects the Developer knows all the Rules, he/she must immediately change some or all of the Rules.
  5. The Customer is never wrong.
  6. The Customer can change their mind at any given point in time.
  7. The Developer must never change his mind without express written consent from the Customer.
  8. The Customer has every right to be angry or upset at any time.
  9. The Developer must remain calm at all times, unless the Customer wants him to be angry or upset.

Ok – so the point of that little diversion was simply that the customer is always at liberty to change their mind (even for those projects where requirements are seemingly ‘locked down’ – such as fixed-bid type of projects).  Agile’s whole purpose in life is to handle any and every curve ball that the customer can throw at the development team. In the pursuit of Agile, I find two areas where development teams get the intent of Agile all wrong.

This post discusses these two common Agile tenets and their misinterpretations.

Common Agile Tenet 1 – Only program the system to meet the current requirements.

Flat-Footed interpretation of Agile Tenet 1 : We can start coding anytime – even if some of the more critical requirements are not currently available.

Agile does not say that you should begin coding without requirements. Agile does not say that you should use the ‘start with current requirements’ as an excuse for not flushing out the important missing pieces up front. Agile’s intent here is simply to let you know that your system must be designed in a way to accommodate change. It is not saying that your system must be designed using an incomplete or inaccurate blueprint.

The simple example below may help illustrate this.

An Example: Building a simple contact form (web form):

Say you are tasked with building a simple contact form – just your everyday firstname, lastname, address fields, email etc. On the address fields, the customer is unsure about:

a) Whether they will allow a single ‘address’ for the customer or multiple addresses (e.g. Amazon.com)

b) Whether they allow a single contact per address (e.g. a typical consumer shopper) or multiple contacts per address (e.g. a business office location)

Incorrect Interpretation of Agile Tenet 1 (Start with whatever requirements you currently have’)

 

 

         Let us build they system assuming a single address only – and a single contact per address. If it changes down the road, we can accommodate that change.

Correct Interpretation of Agile Tenet 1

  Answers to the specific requirements above (single address versus multiple addreses, single contact versus multiple contacts per address) can dictate the entire nature of the code at the UI layer, business layer as well as the data layer. In effect, the question is about whether the Contact—Address relationship is a 1 to 1 relationship (the simplest scenario) versus a 1 to many versus a many to many. We all know intuitively that at the database level, this is a big deal and affects the very design of the schema objects. It is no surprise then, that the domain (business entity) layer, which is an OO representation of the database schema, will be hugely impacted by this decision. And the business objects layer which contains the core business logic, will depend heavily on the domain layer. The UI layer, of course, is the most damned by this decision since it not only has a dependency on the business objects layer but also has to worry about different types of controls to accommodate the changes.

You might argue that all of these things can be done later on (adding DB constraints, changing single select drop downs to multiple selects etc..). However, extrapolate that single contact form to multiple forms, tied to a large business layer tied to a data access layer tied to an entity layer which finally ties to the database, the change is no longer simple. It could (and usually does) mean days and days of rework and code changes.

The real question should be:  ‘Why do we not have these important requirements upfront?’  Is ‘Agile’ being used as an excuse for ‘we’ll worry about it later?’

Start with as complete a set of requirements as you can get – especially when it comes to core features. Push the customer to provide these if they are not easily forthcoming. Agile (or any software development process for that matter) relies heavily on having as much information up front as possible. The only thing Agile does better than others is handle changes when they do happen (via the second Agile tenet – comprehensive unit tests).

Summarizing Common Agile Tenet 1

This common misinterpretation of ‘Start with whatever you have right now’ typically leads to inflexible software design which is not well suited for changes down the road. This simple misinterpretation can add weeks (and thousands of dollars) to any development budget. It typically involves an entire revamp of one or more layers of the application every single time the customer changes her mind. Instead of being an Agile sprint, the process has turned into an expensive, flat-footed marathon.

Enough about Agile tenet 1 (incomplete requirements). On to the second culprit.

Common Agile Tenet 2 – Comprehensive Unit Testing

The second often ‘misinterpreted’ tenet of  ‘agile’ is:

“Oh yes – we do agile – but we just don’t have unit tests in there yet. We make it optional for developers and some of them haven’t gotten around to the unit tests. “

This is the exact opposite of agile! If you are holding daily scrums, doing pair programming and all of the rest – but have no unit tests, you might as well throw all your code into the recycling bin. There is no value to the code.  When major feature changes are proposed, a non-unit testable codebase will need to be inspected for every conceivable breaking point manually.  This is as nightmarish as software development can become. The larger the project, the scarier the nightmare.

If the team just had unit tests in place, the nightmare could have been avoided.  How?

“In Agile, Unit Tests are the superhero that catches all the bad guys.” – AV

Unit tests are what identify breaking points for you whenever you decide to change some code to accommodate feature changes.  Unit tests are what let you handle a real curve ball requirement that could potentially wreak havoc on your codebase. Unit tests do not do this alone – but if combined with the following, they will greatly reduce chances of bugs making it beyond the developer’s box (i.e. bugs will be caught during development as opposed to QA or worse (the dreaded ‘Production Issue’). Here is what distinguishes a well designed piece of software:

  1. A well designed object model
  2. A normalized, relational database model.
  3. A flexible business layer that allows for easy modification of underlying object types (using patterns such as Abstract Factory and Interface based design) and
  4. A comprehensive set of unit tests.

The last item (comprehensive unit tests) are what distinguishes an Agile design for a ‘flat-footed’ design. If you were to leave all the others out and still have unit tests in, your life would still be simpler than the opposite scenario. Ideally, of course, you want to have both.

“The opposite of Agile is ‘flat-footed'.  Without comprehensive unit tests, every piece of software is written flat-footed. “  - AV

This makes it incapable of accommodating changes and at worst is a huge liability rather than an asset.

The real power of Agile is in unit tests. Those that are used to writing them know their power. I – for one – can state that on more than one occasion, the unit tests I wrote saved the project from disaster.  How – you ask?

Your customer comes along and says :

“You know what, here’s a couple of additional fields that I didn’t think of earlier – they need to be displayed on so and so form. Oh – and by the way – can you just remove this field along with that? Thanks a bunch.”

The customer says it in a nonchalant manner – thinking in the back of his/her mind – ‘That must be trivial. I’m sure they will knock this out in the next couple of hours’ 

Meanwhile, the back of the developer’s mind is a slightly different animal at this time.  ‘Crap – that means I have to rework the object that I send over the wire, ensure that the additional fields are marked serializable, etc…if I change one of the key objects that is already being used by various other pieces of software, what is to say that they will continue working as before?  In other words, the developer’s mind (the back area to be more specific) is conjuring up all the possible ‘breaking points’ that could reveal themselves as a result of this seemingly trivial change request.

What bridges the gap between the developer’s paranoia and the customer’s nonchalance is something called unit testing. What comprehensive unit tests do is take on this burden of 'detecting breaking points’ that can result from seemingly minor code changes. Provided the tests are written in a way to capture every core business use case (and then some), these little self-contained pieces of code scurry along like an army of ants – finding every bug in the path that is your codebase… Needless to say – what works so well for detecting breaking points with minor changes,  also detect breaking points caused by MAJOR code changes. Unit Tests are the best insurance that code can buy.

“A comprehensive set of unit tests is the best insurance that code can buy….”  AV

Without these tests, you are left manually going over each possible ‘breaking point’ scenario – something that is bound to endear you to your QA team.

Summarizing Agile Tenet 2 – Unit Tests

  A comprehensive set of unit tests is the best insurance that code can buy.  Agile teams start writing tests alongside code. The converse of this is ‘If you are not writing unit tests alongside code, you are not Agile.’  Having been saved by my own unit tests on more than one occasion, I would rank  recent unit testing advances as the single most important development in the software development industry. 

  True – that in the 70s and 80s, people would write ‘drivers’ for their C code – which were essentially ‘tests’ – i.e. software testing software'. However, the sheer proliferation in languages, tools and libraries to facilitate unit testing in recent years takes unit testing to a new level.

In addition, today’s OO software is far more layered requiring test suites at each layer (some of you might argue that the UI layer cannot be unit tested well. While that may have been true a few years back, in recent days, it is entirely possible to unit test UI layers (I blogged some time back about some nifty ways to unit test the UI layer.)

Summary

Imagine a home-owner who decides to remodel a room (say combine two rooms into a single room by breaking down the dividing wall). The ‘Agile’ architect would say – sure – all we need to do is to figure out what the effect of breaking down the dividing wall will be – then we address those issues while taking down the wall – so that the final result is seamless. 

In contrast, our ‘flat-footed’ architect would say – ‘Sure  - all I need to do is take the entire house down -  and rebuild the entire house from scratch – where we should be able to easily build the new room.

   Sound far-fetched?  In my experience, these flat-footed practices (starting coding with incorrect, incomplete requirements  and not writing tests for alongside code), are not only rampant, but are often, like evil twins, found in pairs.  As recently as a project over at the Texas Education Agency, the team continued to revamp the system everytime the customer changed his mind (which was frequent).   Coupled with the fact that there were no unit tests in place, this process came at an enormous cost – in terms of both - development and testing time.

Agile is here to stay. The real question is  -  “How is your team interpreting ‘Agile’?”.  Just holding daily scrums and sprint planning meetings do not make a team Agile (see my related upcoming post on Scrummy Development versus Crummy Development)‘.  The ultimate test of whether you have implemented Agile correctly is how long it takes you to make changes that are potentially ‘breaking changes?’. 

An agile system catches these breaking points for you whereas a flat-footed one makes these much harder to catch. Some of these ‘’breaking points’ may even make it to the production system, since it is often impossible for QA teams working under already stressful timelines to catch all of these. If this was a medical practice, that would be equivalent to releasing a post-operation patient with the scalpel still inside his body. 

If you are going to do Agile, do it right. Simply holding daily scrums, doing pair programming etc. does not make a project agile. Making sure your code can easily handle the toughest requirement change thrown at it, is what distinguishes Agile software from flat-footed code.

Answer to the riddle “Voiceless, it cries, toothless, it bites..” – The Wind.

Tags:
Filed Under: