he things that we tend to do poorly on software projects are also things that we tend to do often. These things also tend to be small enough to slide in under our pain threshold. They’re too insignificant to earn a high-priority position on our to-do lists.
Agile developers do many small things well. Taken in isolation, one might think that any given one of these small things is inconsequential. By allowing ourselves to neglect these small things, we allow their detrimental effect to be compounded as a project progresses or as a product ages.
Collectively, the sum total of the constant detriment of these small things saps more productivity from our development efforts than we can ever recover from extravagant development tools and management intervention. Until we do many small things well, the mere use of “powerful” IDEs is a second-rate fall-back position from what should ordinarily be a sustainable and enjoyable software development experience.
To bring a deeper focus on ever subtler and finer concerns, developers must abandon their attachment to the command and control approach typical to traditional development process. A project would lose its forward momentum under the weight of managing and tracking all of the additional micro-iterative steps and micro-incremental design and implementation tasks.
Agile teams self-organize around delivery of the product rather than the conformance to a project plan that is laid out far in advance of the actual software development work. They are accountable to the working software rather than the individual line items on a Gantt chart.
If you plan to swim across the English Channel while weighed down with cement boots, you have a couple options to make it work. A pre-agile swimmer would get the most advanced personal flotation device he could find that would counteract the effect of the boots while not restricting his swimming motion. The agilist would grab the first low-tech object that he could effectively use as a hammer or a chisel and remove the cement boots.
Agile development unapologetically dispenses with the constraints weighing down traditional software development approaches. That doesn’t mean that agile projects operate in chaos. Agile projects and teams typically operate with higher discipline than traditional projects and teams, but the discipline is focused on software design and implementation rather than prescriptive design and micro-management.
Agile development jettisons the unnecessary overhead that has grown from trying to wedge software development projects into defined manufacturing processes rather than using the empirical manufacturing processes that are much more natural to software development work.
Somewhere in the lost pre-history of software development, some mythical programmer archetypes chose how the generations of programmers that would follow did software development. They would choose between defined process control and empirical process control. Their choices may have been appropriate to their work at the time, but here in the present-day software development world, we’re doing little more than mechanically following the kind of professional superstition that kept 15th century sailors from sailing off the edge of the world to be snapped up by one of the elephants on whose backs the flat Earth sat, or by the giant turtle on whose back the elephants stand.
Traditional software development methods are concerned primarily with prescriptive command and control, both in management and software design efforts. Agile methods are concerned with inspection and adaptation in the face of the unending parade of surprises in a software project that inevitably invalidate the unfounded suppositions made by prescriptive command and control.
Agile development confronts us with the essential issue in empirical process control: Why take an action as if you were in possession of all the facts at a time when you can’t possibly be in possession of all the facts?
When we face the reality of software development processes as empirical processes, we can deal realistically and responsibly with software development without the overhead involved in keeping ourselves in denial:
- We move forward with eyes wide open, inspecting and adapting as we go.
- We constantly validate our assumptions with real users and real customers, giving them the opportunity to validate their own assumptions of their needs based on hands-on experiences with actual, working software.
- We keep our systems in a deployable state, giving our customers the opportunity to stop development once they realize that they have enough working software in their hands to get their jobs done now.
- We keep our code clean, literate, and readable knowing that we need to constantly revisit it to incorporate adaptation.
- We keep designs simple knowing that complexity is the great productivity killer.
- We keep designs concrete knowing that abstract patterns are often harder to adapt.
- We write tests that allow us to prove that any adaptations to code haven’t introduced bugs.
- We build micro-incrementally and micro-iteratively from the outside to the inside using specification-driven and behavior-driven practices like Test-Driven Development.
- We work as a collective, eliminating slack space in human resource allocation, and constantly reviewing the simplicity and quality of our implementations and designs.
Traditional software development approaches are a constant struggle to swim against the current without recognizing that the struggle is the current’s way of telling the swimmer that he’s swimming in the wrong direction. We have simply taken this struggle for granted as an inherent part of software development.
Agile development is an effort to look at the inherent reality of software development, and to build a process that allows a team to flow with that reality. There’s no point in struggling against the current when you can just enlist its energy to propel your project.