A core idea in agile software development is that we don’t know enough right now so we should only build enough for what we actually do know right now. This is sensible. This idea underpins evolutionary / emergent / test driven design – allowing them to thrive. If we can safely and confidently change the system in any direction from where it is now, then we are in a good place. We are keeping the XP cost of change curve as flat as possible.
But the cost of change may become high if we need to continuously rework everything. If the knowledge is available to help make more informed design choices earlier, we should use it.
Know where the code is going
Good software developers are intentionally trying to make the code base better. This is highly desirable. Good software developers will refactor confidently and allow new designs to emerge. When you have 6 good developers refactoring the same code base into what in their minds is the best solution it is plausible that you may land up with 6 very different designs going in 6 very different directions. This might not be ideal.
What would make those 6 good developers into a great team is a shared understanding of how the code is being refactored so that we don’t land up with 6 different designs, but rather one collaborative design that everyone has contributed to – pulling it in the same general direction.
As a team, discussing about where we’re refactoring the code to is important. A given pair might not reach the best design while working in this sprint and another pair may augment and grow that design in the next sprint. If we share where we’re going, we can hopefully get somewhere in the region of the shared destination. And we can more meaningfully converse about changes in design as the requirements change and agree on the next destination.
But don’t inhibit innovation and new ideas
The counter to this is that if a good developer is building something and they choose to build something different to the current design – maybe it is simpler, better, cleaner – this should not be inhibited. Do not strive for uniformity and accidentally crush the very innovation that you need to channel from a good developer in order to have a great team.
Know where the business is going
A common way of breaking up stories is around the CRUD screens / actions. It is sometimes easy for a Product Owner to define a series of screens that allow them to administrate some set of information. It is plausible that these screens are built without a conversation of why the screens are being built. Possibly this is because the PO doesn’t yet know the exact details on how these things are going to interact. But if this is the case, it is plausible that when the PO finally specifies how these CRUD things are going to interact in a meaningful way that the team could turn around and suggest that, based on how those screens have been built, that isn’t possible – or at least it is very hacky and we’re already building a legacy system with bad design.
Knowing something about where the business is going in the next sprint or 3 is useful. Use it to track how the design is evolving and hopefully take this at least somewhat into account when designing the code.
But don’t future proof too soon
Don’t worry too much about planning for future needs that are trivial to add in a future sprint. We don’t need to future proof the design. We only need to know where it might go so that we can perhaps go there more easily later. We need to know that the short/medium term goals will be supportable by the design we are creating today. If it isn’t, it doesn’t matter too much, but the cost of change will probably go up if we need to massively refactor the entire system every sprint – so what can we do to help avoid that?
Know where the architecture is going
Systems are continuously evolving. As architectural issues arise, an idea of what should be done to solve them should be discussed. If we can agree on the direction that we need to move the overall architecture and understand what it could look like, then any team may be able to start building that within existing work that they have, in an opportunistic way. If we have no clue where we would like to go then any team will probably continue to do exactly what they are doing now.
Alternatively, any team may start to innovate in different directions and again we may land up with the architecture of the system being pulling in several different disparate directions which may not be a beneficial in the long run.
If your teams discuss and plan what the architectural changes could look like, then we know where we’re going and we can start working out the baby steps to get there. Those baby steps may be started to be done inside current work. But without any clue of where we going we can’t even start to take any baby steps.
But don’t be too constraining
Architecturally knowing where you’re going is important – but the micro details shouldn’t be constrained. It shouldn’t matter if we use redis or memcache in terms of an architectural solution. Let the teams converse and decide as a group on the actual solution details when they are needing the solution and allow that to be based on the real experience and constraints they are being experienced in their teams.
Know sort of where you’re going
The precise destination isn’t important – the general one is. The details will vary. The overview of the destination over the next 2-3 months hopefully will grow and evolve. Despite that, hopefully it will still be comparable enough to call reasonably the same.
How abstract the destination is depends on the need. For instance, it might be useful to sketch out the boundaries of several micro-services to have some idea of the destination and to give teams an idea of what they could break out of a larger system. But don’t be married to those decisions if they turn out to be incorrect.
Use the knowledge just in time
Knowing the destination today should inform the code as a potential destination to refactor towards. We shouldn’t be focusing solely on the road directly in front of our feet. We should be looking up into the horizon and gleaning any knowledge we can of what is up ahead.
Knowing where we are going will allow the whole team to pull the code and system in a similar direction.
Knowing sort of where we are going should lead to an informed just in time decision about when to do something with that knowledge.