(Riddle: “What is voiceless, yet cries and toothless, yet bites..” Read to the end to see the answer..)
- Agile – Software that adapts well to change (is well-designed and has comprehensive test coverage)
- Flat-Footed – Software that is NOT agile.
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 say much about my learning ability! However, living by the maxim that quality trumps quantity, I plod on…).
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 her mind (about anything) later, but the software must be tweaked/revamped as needed to accommodate the changed requirements. I remember a poster from college titled:
‘Rules that Women would like to share with men’…
- The Woman always makes the Rules.
- The Rules are subject to change at any time without prior notification.
- No Man can possibly know all the Rules.
- If the Woman suspects the Man knows all the Rules, she must immediately change some or all of the Rules.
- The Woman is never wrong.
- The Woman can change her mind at any given point in time.
- The Man must never change his mind without express written consent from the Woman.
- The Woman has every right to be angry or upset at any time.
- 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
- The Customer always makes the Rules.
- The Rules are subject to change at any time without prior notification.
- No Developer can possibly know all the Rules.
- If the Customer suspects the Developer knows all the Rules, he/she must immediately change some or all of the Rules.
- The Customer is never wrong.
- The Customer can change their mind at any given point in time.
- The Developer must never change his mind without express written consent from the Customer.
- The Customer has every right to be angry or upset at any time.
- 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.
The two agile tenets that are most commonly misunderstood/abused are:
Agile Tenet 1: Only program the system to meet the current requirements
Agile Tenet 2: Write comprehensive Unit tests
Misinterpretation of Agile Tenet 1 – Only program the system to meet the current requirements.
Flat-Footed interpretation (misinterpretation) 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)
“Flat-footed approach” : Builds the system assuming a single address (instead of accommodating the possibility of multiple addresses) – and a single contact per address. If things change down the road, they anticipate that they can accommodate that change.
Correct Interpretation of Agile Tenet 1
Answers to the specific requirements above (single address versus multiple addresses, single contact versus multiple contacts per address) can dictate the entire nature of the code. The UI layer, business layer as well as the data layer all depend on this simple decision.
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 (the most complex scenario).
At the database level, intuitively, we understand that this is a big deal. It should come as 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. 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 ‘multiple relationships’ as opposed to single 1-1 relationships.
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?’
Consequences of misinterpreting 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.
Misinterpreted (flat-footed version of) Agile Tenet 2 – Comprehensive Unit Testing
“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 anti-thesis of agile development! Holding daily scrums, doing pair programming and all of the rest can not make your software agile. Only unit tests can! 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.
Just having unit tests in place can avoid all these issues.
“The ‘Agility’ in Agile comes from automated unit tests”.
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’). What distinguishes well-designed software from poorly designed software:
- A well designed object model
- A normalized, relational database model.
- A flexible business layer that allows for easy modification of underlying object types (using patterns such as Abstract Factory and Interface based design) and
- A comprehensive set of unit tests.
The last item (comprehensive unit tests) are also what distinguishes Agile software from ‘flat-footed’ software. If you were to leave out the first three and only have the last item (comprehensive test coverage), you would still have agile software. You may argue that what is the value of having ‘agile’ software that is not ‘well-designed’.
This leads us to the second redeeming quality of unit tests – they force you to refactor your code – so it becomes better designed.
Unit tests, by their very nature, force you to look at your code with a fine tooth comb. For example, if you approach writing a unit test for a ‘GetCustomerInfo’ method, you may realize that the method is trying to do too many thing (connect to a data source, fetch the data, assign the data to a business object etc.). Instead of doing all of that, you reason that it would be better to break that method into a few smaller methods – each of which does one specific thing. Already, you have refactored your code and made it better before you even wrote your first test!
Repeating this process leads to highly refactored code which can be read and understood easily by a new developer on the team. More importantly, during troubleshooting, it helps to quickly pin-point a problem down to a single, small ‘culprit’ method as opposed to a gigantic block of code.
Summarizing Agile Tenet 2 –Comprehensive Unit Tests
A comprehensive set of unit tests is the best insurance that code can buy. Agile teams start writing tests alongside code. Some managers argue that they have a team of testers ready to catch all bugs prior to launching the application into production. To them, my response would be:
An agile system catches various ‘breaking points’ for you. In lieu of unit tests, 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.
Consequences of misinterpreting Agile Tenet 2
Makes your code incapable of accommodating changes – making it a huge liability rather than an asset.
- Agile is here to stay. The real question is – “How is your team interpreting ‘Agile’?”. The ultimate test of whether you have implemented Agile correctly is how long it takes you to make changes that are potentially ‘breaking changes?’.
- 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 and quickly handle the toughest requirement change thrown at it, is what distinguishes Agile software from flat-footed code.
Answer to the riddle posted as a teaser to this blog post – “What is voiceless, yet cries and toothless, yet bites..” – The Wind.