Product architecture is not a fixed thing but rather a spectrum of decisions. Key aspects of your product are costly to change and you need to get them more right early on. Having expensive decisions ’emerge’ would be dangerous. Other aspects you might not know well enough and you need the flexibility of emergent design.
Coaching teams, I commonly come across the question around architecture and agile. It seems somewhere lost along the ‘agile’ way is the basic need to have systems that are stable as well as flexible. Cloud, containers, and microservices (to name a few) all are promising ‘enterprise agility.’ While these are important concepts, as per most technologies and processes, blindly latching on to them causes new and different pain. Here are some simple ways we are helping teams balance architecture and technical needs with product delivery.
- Understand the assumptions of the architecture
- Instead of over analyzing what architecture, shift to when an architectural decision is important
- Look at the roots of the interest in the technology
- Reflect if you are ready for such a move
Understand the assumptions of the architecture
Architecture is a set of decisions we make based upon our understanding of the problem, where it may go, and how quickly. Context is always key here. I have worked with teams where, in their first 2 sprints, they just wanted to ‘get the architecture right.’ When asked what right meant, in what context, they weren’t certain – they were removed from the need of the product and too interested in figuring out how many instances of a database to spin up.
When working with teams around architecture, ask them what assumptions are they making about the product that this architecture solves? Then, and sometimes most interestingly, what happens if we are wrong and how would that alter the design? Could we do anything now to make the architecture less rigid and more malleable? If we can’t think of anyway the architecture could be wrong, then quite possibly we do not understand the product need well enough.
Instead of over analyzing what architecture, shift to when
Microservices and containers seem to be all the rage these days. And they are cool technology. Like most newer, hip ideas, developers can get too wrapped up in the coolness and start introducing accidental complexity.
Recently we had a team where the architects said this new app (that they would not be personally writing) – had to be ‘cloud ready.’ The delivery team therefore had to develop everything as microservices and use docker (as well as RxJava) – all technologies that were brand new to the team.
While those are interesting technologies that do solve problems, instead of starting right off the bat with a new team learning 3+ new technologies / libraries, we instead looked at the product – when would these technologies make sense? If we used microservices, do we know now what would make sense as a service with intelligent routing? Do we even need ‘burstability’ in the cloud now? We used a storymap to look at when certain decisions would make sense as well as what about the product we would need to learn to make the best decisions. We used targeted learnings and loosely coupled code to defer architectural decisions.
Don’t jump into architecture blindly. Use product context as a guide.
Explore the roots of the interest in the technology
At times, teams jump to architectural decisions prematurely or without understanding what they are really looking for. Using the same example above, microservices could be a good pattern. But, in the case of that team in particular, there was no idea of how the services should be made independent, how they would scale, orchestrate, etc. In that example, just building microservices was irresponsible.
I have also seen a team with a decent working product pushed to ‘make it microservices now.’ By doing so, they unnecessarily over complicated the build and deploy side of the product. This unnecessary complexity then made product learning more complicated and error prone.
In both situations, microservices might have made sense. In reality, what teams (and the architects) were looking for were more loosely coupled systems. Once we worked with the teams and architects to talk about loosely coupled systems as a design practice that is especially inherent when using test driven practices, the microservice noise went away.
Understand the root of why the architecture is interesting – perhaps you can get there without a buzzword?
Reflect if you are ready for such a move
I believe I first read it in a Jerry Weinberg book – ‘If you can’t think of 3 ways something can go wrong, you might not understand it.’ Apply the same thinking to your decisions around architecture. What could go wrong with a non-relational database? If those items happen, are we ready – from a product / customer perspective as well as operationally – to support those challenges?
I recently worked with a team that was discussing using Spring Boot. Spring Boot is nice, but a very opinionated way of building a product. This organization was investing a large amount of time and skill around building a community around configuration, automation, openstack, etc. If this team went with Spring Boot and its embedded run time (just deploy the jar) – they would be sacrificing a large amount of the help that was already there for them. Additionally, there were components of Spring Boot that the team wasn’t skilled in. The bright, shiny object syndrome was there – Spring Boot would get them going fast, but ultimately it was a move they weren’t ready for. That team ended up going a simpler Tomcat route with a small service layer and Hibernate. They were up and running quickly and able to leverage their internal Chef community.
Not all architecture can be ’emergent.’ Even more importantly is the fit between the architecture and the product. What have you seen with architecture in the search for product delivery that has worked well?