https://dev.to/simonbrown/software-architecture-isn-t-about-big-design-up-front-4hol

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/77d45bc8-f5cb-4ac6-9b54-f033f12c8146/vageoe01nsosj565s08u.png

Five things every developer should know about software architecture (5 Part Series)

Software architecture has traditionally been associated with big design up front and waterfall-style delivery, where a team would ensure that every last element of the software design was considered before any code was written. In 2001, the "Manifesto for Agile Software Development" suggested that we should value "responding to change over following a plan". Unfortunately, when taken at face value, many teams have misinterpreted this to mean that we shouldn't plan. The net result, and I've seen this first hand at numerous organisations around the world, is that some software development teams have flipped from doing big design up front to doing no design up front.

Big design up front is dumb. Doing no design up front is even dumber. Dave Thomas

Both extremes are foolish, and there's a sweet spot somewhere that is relatively easy to discover if you're willing to consider that up front design is not necessarily about creating a perfect end-state. Instead, think about up front design as being about creating a starting point, and setting a direction for the team. This often missed step can add a tremendous amount of value to a team, encouraging them to understand what they are going to build and whether it is going to work.

Significant decisions

In order to arrive at a software design, you need to make some design decisions. In discussing the difference between architecture and design, Grady Booch tells us that "architecture represents the significant decisions, where significance is measured by cost of change". In other words, which decisions are expensive to change at a later date?

A good way to think about up front design is to ensure that you've made and understand the trade-offs associated with the "significant decisions". These significant decisions are typically related to technology choices (i.e. programming languages, frameworks, protocols, products, etc) and structure (i.e. decomposition strategies, modularity, functional boundaries, etc).

If you're building a monolithic software system, the choice of programming language is likely to be significant for a number of reasons. Adopting a microservices architecture potentially reduces the significance of which programming language(s) you choose, but introduces other trade-offs that need thinking through, including some that are sociotechnical in nature. Similarly, adopting a hexagonal architecture allows you to decouple your business logic from your technology choices, but again there are trade-offs.

The up front design process should therefore be about understanding the significant decisions that influence the shape of a software system rather than, for example, understanding the length of every column in a database table. In real terms, I'd like teams to understand what they are going to build, how they are going to build it (at a high-level), and whether what they've designed will have a good chance of actually working.

How much up front design?

But, how much up front design should teams do? This is one of the questions I'm asked the most, with agile teams often confused about how much up front design they should do, or whether they should be doing up front design at all! My recommended approach can be summarised as follows:

"some" is quite a vague amount of up front design, and it's one of those "it depends" type situations where context matters. Some teams can get away with doing very little up front design, others will need to do more. Perhaps a better approach is to think about up front design being an iterative and incremental process too, and asking, "when should we stop doing up front design?" instead. My view is that you should stop doing up front design when: