Writing Shippable Code (Part Two)
Writing Shippable Code (Part Two)
The first part of this article introduced the concept that developing a complex software system was like going on a journey. I contrasted how we plan our journeys through the use of route planning systems against that of an agile journey which is more like using a GPS in our car. I also introduced the idea that we only know when we have reached our journeys end (being completely done) when we have demonstrated that we have fully satisfied the expectations of the customer, our criteria for a successful outcome and that we can use this thinking throughout our project so that each iteration delivers software which can achieve a successful customer outcome.
In this months article I will explain how we express the criteria for a successful outcome in the context of our software system and will uncover a loophole many agile teams overlook. Part three will then conclude with demonstrating how this can be overcome in our code so that we can deliver shippable code. It may help you to read / recap part one as I will continue where that left off.
I don't like GPS
Not everyone likes or gets on with a GPS. This first thing people do after purchasing one is to request a route they have done thousands of times, they could even do it blindfolded if it was legal. It works and suggests roads they would have chosen. We do this to validate whether we will get a successful outcome before we use it anger. But how will the GPS system compare to the old method? Your passenger used to call out the various road changes and junctions as they approached. What role do they now play in your journey? Will they sit back and enjoy the ride? Maybe they start to suggest alternative directions during the journey so that you end up switching it off. Our managers begin to feel redundant like our passengers as they no longer need to chase round asking how we are getting on, instead our count of passing tests v total tests to pass does this automatically for them.
Although test code is short term overhead, longer term it's an essential safety-net ensuring that the journey towards our destination (shippable code) doesn't end up leaving a trail of debris (defects). Having the test code accelerates our productivity by allowing us to deliver more functionality than previously since we have increased knowledge of what is and what is not working. Management have spent many years delivering and testing products the old way, they often see no value in the new and will attempt to steer any agile transformation (especially automated testing) back to their old comfortable way just like our redundant passengers.
Agile development has for some time been heralded as the new new way to develop software. The agile manifesto itself encourages a different way of thinking about how we go about delivering code. There are extremists though who in many ways go even further and hitchhike their way through development. Only looking at where they are now without regard to where they need to get to next. They jump on the next iteration to take them a little way in the direction they are heading and continue doing this until they reach their destination. There are often several unknowns to this way of travelling; projected journey time, estimated journey costs and level of completeness throughout the journey. Though for some journeys this means of travelling is quite acceptable.
However, after each iteration, they reflect on where they are, making directional adjustments to ensure they will reach their destination. Sometimes even backtracking when taken down the wrong road. They only design the area of the code they need and only focus on what is currently known adapting this as their knowledge increases. If we coupled this thinking with knowing our criteria for a successful outcome (testing our assumptions as we go) we would have much higher confidence in that we have only produced (code) what was actually needed and that it does meets our customer's expectations. Maybe we need to give our hitchhikers a GPS "At the next interchange, flag down the sliver lorry who will take you 4 miles southbound, depart there and collect the red truck heading north. Your total estimated journey time is two hours."
Successful Customer Outcomes
For us to effectively test our assumptions as we go we need to understand how we determine what a successful outcome is and how we can begin to express this. All processes have a criterion for a successful outcome and the judge for this is neither us nor our customer, but the end customer, the individual who is going to use our software. As an end customer I have an expectation of what the system is going to provide for me. If it does not meet my expectations then we do not have a successful outcome. If it does, I'm happy and we do have a successful outcome. This simple view is often missed by most development teams and often lost in translation when applied to software development in general.
If we have been commissioned to develop a system for another company who themselves have customers or have a marketing / product planning division who speak on behalf of our customers, our viewpoint on "value to the customer" is somewhat different to the end customers. We end up neglecting the real customer and fail to consider how our system will perform in their eyes.
Comparing our criteria for success (as developers) against the end customer's we generally get two different viewpoints. We find it difficult to see through the eyes of the end customers leading to these differences. However, we spend most of our lives being end customers to other people's systems. So why is it so hard for us? Especially when we are quick to complain if a system we interact with doesn't do what we expected. We forget that each time we interact with a system one of two things can happen. Firstly, everything goes well and we are happy, we might not even notice that we have interacted with anything because things went so smoothly. Secondly, it could go wrong or not quite as we had expected. We have witnessed a failure point and this taints our perception of the overall system. As we continue interacting with the system our feelings snowball when we discover more and more of these. How many times have you dealt with a system which come the end of your encounter you vow never to return? This could be a shopping website, a mobile phone, software on your PC or even a utility / insurance provider.
As we define systems with more and more end customer interaction we increase our potential to displease. Minimising the quantity of these interactions is one approach in reducing this risk, another is to ensure that for each interaction we have viewed our system as if we were the end customer, considered what the criteria for successful outcomes are, and understood the impacts of not achieving these. Remembering that to do this we have to put on our end customers glasses and see through their eyes.
All software attempts to encapsulate a process for our end customers. It could be the process of finding and booking a holiday, purchasing something online, printing off a document or even taking a photograph on our digital camera. These all are driven by software following a process to give us what we need. Each time we interact with this process we have a touch point. We have touched the process.
To illustrate this let's take a photo with a regular digital camera: -
1. Switch Camera on
3. Locate subject in view finder
4. Zoom in/out as required
5. Press the Shutter button
6. View the picture on the internal LCD
7. Switch the camera off
How many touch points are there? The answer is seven. Every step we are doing something and our expectation is that they are all going to do exactly as we ask. It is possible to simplify our process by reducing the number of touch points, making it easier for our end customer to use. Most digital cameras for example, combine the first two steps into one eliminating one touch point. Although, reducing too many touch points can leave you with a system that is not usable.
Touch points do not have to be human interactions. They could also be interactions with other systems. For these, expectations for successful outcomes are more clearly defined as there usually is a published interface detailing precisely what is being expected.
Moments of Truth
Our expectation is that every step in our process is going to do exactly as we ask. But what if it doesn't? What if you cannot get past step one? How do you feel? For our camera example it could be the battery, so we change the battery. What if any of the other steps fail to perform as expected? This is the moment of truth, the moment at which the system could start failing in our eyes. We have asked the system to do something and if it doesn't we are not happy. It only takes one failing moment of truth in any system to leave a bad taste in our mouths. Every other step in the process could work beautifully, but we have been hurt by the one which didn't.
This is where we tend to introduce the majority of our defects in our system by making incorrect assumptions about what we think is a successful customer outcome. Then failing to test our assumptions as part of the way we develop software. We write user stories / use cases with automated unit test but rarely link them together with the successful end customer outcome. If we did and tested our assumptions as we go (like our GPS) then we would be able to deliver with confidence, we would genuinely have shippable code.
Where are we going?
Knowing our final destination when developing a complex software system isn't as cut and dry as it is with a GPS or a route plan. For the latter we know the town or city we are aiming for. Most of the time we even know the precise address. However, by taking a step back and looking at our software system as a whole we can capture the overall successful customer outcome we are aiming at achieving and use this as our clue to our journey's end. We know that once we have provided a system that meets our end customer's expectations through successful outcomes we are completely done. You can capture this high level outcome as your system goal. I recommend that you print this out as large as you possibly can and post it up all over your offices. Let everyone be reminded every minute of the day exactly what it is the end customers are expecting us to do for them.
While this is good for identifying the overall direction we are travelling, how can we ensure that throughout our journey we are not deviating away? To help us, we shall look at how we determine what value to the customer is.
Lean software principles, in fact lean in general, categorises steps within our process as value, waste or apparently necessary waste. Assessing whether a customer would willingly pay for a process step allows us to assign the appropriate category. We can apply the same thinking against the underlying software process encapsulated within our system. We use apparently necessary waste as a marker for those aspects of our process that the customer would not willingly pay for but is still a business requirement, or seemingly adds value to the business.
Whist I agree to these definitions, they do not go far enough for me. They allow us to have steps in our process that we think the customer would willingly pay for, but do not actually contribute towards a successful outcome for the end customer. In fact what this manages to do quite well is increase our risk of failure. What if it is this part of our system which is failing in the end customer's eyes? They are not going to be impressed despite how good the rest of our system is. This is the loophole with lean software and agile thinking which leads to us developing systems that have a significantly higher degree of risk of failing. This is where the majority of defects in our system arise. A classic example of this is a feature of our software which when delivered achieves the marketing intent of the feature, but in the hands of the end customer doesn't make intuitive sense. The end output is correct, but the steps taken to get there are so convoluted that the end user gets frustrated near to the point of giving up. Certain Ajax implementations on the web fall into this trap by trying to be too jazzy with Ajax without considering the end customer's expected outcome. If it had been considered carefully then only areas where it was necessary would use Ajax, all the rest is wasteful.
To overcome this loophole, I would clarify the lean definitions for value and waste as follows:
Something that not only the end customer is willing to pay for, but also contributes positively towards their successful outcome.
a) Something that the end customer is not willing to pay for.
b) Something that the customer is willing to pay for, but does not contribute positively towards the end customer's successful outcome.
For example, I would be willing to pay for a data entry screen on a holiday booking system to enable a search that matches my holiday criteria. However each time I change my holiday criteria I have to key in all the information again. My expected outcome is a confirmed holiday booking, having to re-enter all my information time and time again only leads to me getting frustrated with the system eventually to the point that I might give up and look for another supplier.
With these definitions in mind we can assess our understanding of our system (new or existing) to determine the impact of the touch points and moments of truths we have, and how we can mitigate them to ensure positive successful outcomes. Using positive successful outcomes as both our unit of distance through our journey and our criteria for completely done we can begin to show (like our GPS system) precisely how far we have travelled and precisely how far we have left to go.
The final part of this article will continue this theme and conclude with how through our code we can close this loophole so that we can deliver shippable code with confidence.
About the Author
Sean Sheehan is a lean software transformation manager for a leading embedded control systems company which he has been with for nearly 10 years. A master black belt candidate for software design for lean six sigma, certified lean six sigma black belt and certified ScrumMaster with over 20 years software development experience in embedded c++. Sean is currently assisting lean software / agile transformation within his current division helping transform three groups from different time zones in applying these techniques collectively. You may link with him at http://www.linkedin.com/in/spjsheehan.