In part one of this series, we outlined some specific examples of complexities that today’s software architects may consider. And we considered how each potential complexity must be justified because each “best practice” has a corresponding context. Finally, we outlined a simple two step process for lean software architecture:
- Build the simplest thing that could possibly work
- Focus on the pain
In this post we’ll consider step one in more detail.
It’s easy to get in a rut as an architect. One can find a few favorite technologies and patterns that seem to do the trick and start using them religiously. To avoid this tendency, I propose starting with the simplest thing that could possibly work. This angle minimizes commitment to an application that may not pan out in the first place.
Though projects fail for a variety of reasons, common mistakes include building the wrong thing or building the right thing too late. Software is merely a representation of the world around us, and that world is always changing. So getting the application out the door as soon as possible helps minimize the risk of investing excessive time and money on building something no one wants anymore. Building the simplest thing adds value by thinking more like a business person and less like a religious geek.
So what is the simplest thing? Well, that will of course vary depending on your needs. If you code in a test-driven manner, then you’ll need to introduce more initial complexity such as consistently coding dependencies to an interface and using dependency injection in order to support this activity up front. That said, in the real world many teams either lack skills in TDD or choose not to write automated tests for sufficiently simplistic applications. For such teams the simplest thing may involve a more monolithic application that mixes business logic and data access concerns together in the interest of speed and architectural simplicity.
Many variables determine the level of complexity that is justified for a given app including team seniority, timelines, application lifespan, security concerns, and the potential for reuse. Even development speed considerations have merit here – more senior teams may perform best with a logically layered application while more junior teams may find the complexity of a more enterprise level architecture confounding and thus an impediment.
Here’s a quick gut check question to gauge if you’re thinking lean enough: Imagine you’re paying other developers to write code and it’s your company – would you require everything you’re prescribing for this particular situation?
In the third and final part of this series (publishes 1/23), we’ll discuss how to determine when it’s time to introduce additional complexity into the architecture by focusing on the pain.
This discussion just scratches the surface of architectural considerations. To learn more about thinking pragmatically about software architecture, check out my new course “Architecting Applications for the Real World in .NET” on Pluralsight