We should always be trying to learn; every day we come into contact with new information, with new ideas, and with feedback on our previous efforts. This should profoundly change our approach, based on a simple and fundemental truth:
We always know today the least we will ever know!
We should expect that our knowledge will grow, whether this is our knowledge of the business or the domain, our knowledge of the technologies and patterns we are applying (and their quirks!) or anything else. This can be scary, but really is very powerful, if we can harness it to our advantage. However, we have to embrace this, and change our ways of working to allow us to respond to these changes when they happen. This is the core premise of Agile.
Traditionally, projects have often been built to a phased approach, starting with a design phase, where the whole system is designed before anything is built. However, in many cases there are core problems with this approach. One is around delivery of value – the lead time before value is first realised is much longer, and value is unlocked in big batches. The other fundamental flaw in designing everything before starting to build is that the design decisions are made with the minimum amount of available knowledge!
It is obviously possible to create a design up front that has no flaws and will work – especially if the problem is very familiar, and the work is very similar to things that have been done before. However, design as a phase means that anything that is learnt after the design phase is complete can’t be applied – or at least not as easily. In the best case, this might mean that the design is built exactly to the original spec with no problems – but can also never be better than the original spec. In the worst case, serious flaws can emerge and it can be too difficult to adapt and rectify them without significant cost.
Admitting to ourselves that we always know today the least we will ever know can be a scary thing, and can lead to paralysis; if we fear making a bad decision because we believe we could learn more before acting, we can get stuck in a cycle of never getting anything done! The best way out of this cycle is to adopt an experimentation mindset: we don’t know for 100% sure what the answer is, but we can make a small controlled step forwards based on our current best hypothesis, and get data from doing so.
If we embrace the concept that we always know the least we will ever know, there are certain things we can do to make the most of this – it can actually be a very powerful thing
- Accelerate our learning by conducting experiments that will build our knowledge quickly and cheaply
- Build small increments that can get feedback, so that we can incorporate this into the next increments
- Build for flexibility and for change, because we expect and welcome the better decisions we can make with increased knowledge
- Treat building our knowledge as a first-class source of value, embracing collaboration and other ways to spread knowledge in the team
Specifically in software, it helps if we:
- Remember that we’re going to be re-shaping out code often – so we need to prioritise readability and ease of understanding (this is always true anyway!)
- Work to interfaces and well-defined boundaries, so that we can replace the implementations of parts of the system easily and cheaply
- Design fast feedback mechanisms into our workflow, like good test suites, and suitable tooling such as refactoring tools with design-time or build-time feedback
- Be especially deliberate in how we structure dependencies, so that swapping out components has minimal impact
- Make every effort to avoid any choice that “locks” against future change
- Aggressively remove friction at every opportunity to enable future change