Deferring decisions can be an effective way of dealing with the inevitable uncertainty that comes with agile software development. When should you actually commit to these decisions? Advocates of lean would argue that there is an “optimal” point for decision making that is referred to as the “last responsible moment”.

One of the earliest uses of the phrase was in the Poppendieck’s “Lean Software Development” which suggested that better decisions can be made when they are based on fact rather than conjecture and it can take time for these facts to emerge. Therefore it is better to delay decisions until the last possible moment, i.e. the point at which failing to make a decision eliminates an important alternative.

In practical terms this means delaying commitment by building the capacity for change into a system. This can involve numerous techniques that should be familiar to developers including using interfaces, abstractions and the separation of concerns to provide flexibility and avoid repetition.

More importantly, it involves a willingness to work towards a minimal viable product that defers the implementation of features that might be required in the future. It is a call to resist gold-plating or dwell too long on the up-front design of the complete solution. Your understanding of a solution will evolve along with your understanding of the implication of any decisions.

Delay shouldn’t mean procrastination

Although the intention is to simplify development and enable faster progress it can have the opposite effect. Delaying decisions can actually be hard work that undermines clarity. Too many open decisions can create mental clutter that impedes progress. Unless there is a strong sense of a roadmap then decision paralysis can set in amidst all the unresolved and inter-related issues.

This is where the problems with the last responsible moment lie. Rather than being a rallying call for greater development velocity it can be an excuse to dodge decisions. Architects can spend too long chipping away at the edges of a problem rather than diving in to the heart of a solution.

The moment that never arrives…

How do you know when it’s the right time to make a decision? There is no clear tipping point that identifies the last responsible moment. There’s just a slow upwards creep of the cost of not making a decision. You can only tell when the last responsible moment has passed, i.e. the cost of indecision has become too great.

The notion of the last responsible moment introduces uncertainty as it doesn’t help you to define when you should be making a decision. In this sense it is just a bad tool as it can’t really be applied in practice. It’s important not to rush into decisions based on imperfect understanding, but it’s equally important to have the courage to make a call based on an inevitable degree of uncertainty.

There have been attempts to define methodologies that objectively identify the last responsible moment by evaluating the cost of delay against the benefit of delay. More direct approaches have even attempted to incorporate financial theory to price options directly and assess them on the basis of relative value. However, this can load decision making with hidden assumptions that conceal uncertainty rather than eliminating it.

There is never a moment of pure clarity where the clouds part to reveal the correct decision. There is always a trade-off and there are always uncertainties. By delaying too long you run the risk of tipping over to an irresponsible moment without realising it.

In the absence of warranties you should always have options

You shouldn’t delay out of habit, but you shouldn’t commit without a reason either. Early decisions can be valuable as they help you to bring focus the solution and remove uncertainty. The trick is to know why you are making decisions and understand how you can respond to changes in circumstances.

Given that designs decisions can never come with satisfaction guaranteed you should seek to minimize the number of irreversible decisions that you have to make. This means thinking in terms of options where you have the ability change course in the future. Design decisions should involve some element of hedging. If things don’t work out the way that you expected them to then you can exercise the option to change.

A practical example would involve ensuring genuine loose coupling between components so implementations can be changed without affecting the wider system. This allows a system to adapt to new circumstances by providing the designer with options for change.

Thinking in terms of options can help to accelerate decision making as you are prepared for changing circumstances. Assuming that change is constant, you are likely to always be dealing with shifting options as part of a longer term roadmap. This may be a more realistic model for decision making than the vague tipping point of the last responsible moment.

About me

I am a London-based technical architect who has spent more than twenty years leading development across start-ups, digital agencies, software houses and corporates.
Over the years I have built a lot of stuff including web sites and services, multi-screen applications, systems integrations and middleware.

My current focus is on enabling scalable SaaS delivery and providing architectural leadership in agile environments.
I currently work as Chief Architect for Wolters Kluwer UK leading them to cloud heaven, one service at a time. Opinions are my own and not the views of my employer, etc.

Recent

There does seem to be growing confusion over what Service Fabric is really for. Is it an orchestrator for microservices? A means of lifting and shifting legacy applications into the cloud? An application development framework?

Azure Functions only provides direct support for a narrow range of authentication providers. If you want to use an external token provider or custom solution, you’ll have to create the plumbing yourself.

ArchUnit is a java library that provides a fluent API for creating self-testing architectures via unit tests. A similar library can be written for .Net Standard that acts on compiled assemblies rather than raw code.

There is a growing sense of unease around how larger organisations have implemented agile. In particular, there is a tendency towards centralised control that can be at odds with the agile preference for individuals over process.