What kinds of considerations do you take into account when designing a brand new system? Do you just take the current hot buzzword architecture and run with it? Do you exhaustively run through the functional and non-functional requirements (the “ilities”) that are important? Just start banging out code and see what emerges?
Growing the System
One of the books sitting on my shelf is entitled Growing Object-Oriented Software, by Steve Freeman and Nat Pryce. I bought this book because the notion of growing the system was intriguing. It is much less about imposing some kind of design on the thing, from the top down, but more about feeling out where the code and the domain want to go. Of course, there is still shaping involved with that; you have to prune the bushes and pull the weeds. But in general, there can be great advantages to just “listening” to the system, and seeing where it naturally wants to go.
Now when designing a new class, or domain object, or refactoring some ugly code, this is a useful strategy. But what about when designing a new system from the ground up? Can you just plant some seeds and see what grows? In a way, yes you can. However, you tend to build in the infrastructure for what you think will be growing. You designate an order for how and where things are planted. You put the tall plants “behind” the short ones. Vines are given lattice-work to cling to and climb up. You separate things enough that they do not interfere with each other, and compete for resources.
So while it is tempting to just sit down and start banging out code, some planning ahead of time is still required. This doesn’t have to be extensive planning; you don’t need to know where each and every seed will go, but you will need to know the general layout of the system (garden), and know how to cordon off sections for particular plants. You will need to know some of the peculiarities of the plants to know where they will fit best.
Buzzword Architecture
When starting a new system, it is very tempting to just pick the current “hot” architecture pattern. This requires the least amount of thought. Developers will be willing to learn this new thing. Frameworks abound. It is ambiguous enough that you don’t have to give any real concrete answers to tough questions. Consultants will leap at the chance to help you design and build this hot new system.
Sometimes, this will end up being the right architecture for the problem. For example, the current hotness, microservices, can fit in a very wide variety of problems. It will be hard to get the boundaries correct, and there are easier ways to start, but microservices can serve well for many business problems. Sometimes, this will end up being a very bad architecture for the problem. Maybe the domain just isn’t big enough to warrant the complexities this architecture imposes. Maybe this architecture just does not let you move fast enough.
When your problems, or your domain, are not very well defined, you may be able to get away with this approach. Start out with something. Without clear direction, it will be very difficult to choose well anyway. So why not just choose the thing that is currently popular?
Understand the “ilities”
When you have clear problems and requirements, it is obviously best to take a look at them. Does any particular architecture fit into those requirements? Is availability more important than consistency?
Of course, these requirements may steer you away from the currently popular architectures. You may find that a monolith might fit better than microservices. This is not bad. Business requirements are a much better indicators for what will be needed than the winds of popularity. Discussions turn more towards the business than to which frameworks have more stars on GitHub.
Architectures are hard to change, so be careful when choosing them. Pay attention to the requirements of the business. Push them a bit, to see which pieces are negotiable, and which are unmovable. Note the limitations that are imposed by a particular architecture.