Introduction to System Architecture and common architecture patterns
Once the domain problem is understood it is time to think about the proposed solution.
Here starts the technical job, the one I like the most. But before talking of code there is a much-needed high-level view: the system architecture to create the design of the complete system.
🏗️ System Architecture
Under this grand title hides a simple concept: knowing what are you going to build. It is not yet time to know how we are going to build.
But we must at least identify the large building blocks necessary to solve the detected problems. Like in the real world, know if we are building a family house, a school, or a corporate building.
🐲 Warning, here be dragons
Traditionally software was created following a strict life cycle: analysis, design, code, test, and deployment. The waterfall model.
Even when these phases make sense they should be applied iteratively. In most cases creating a short cycle that generates value in each loop.
So we should avoid a deep and long design phase that dictates the ongoing future of the project: the so-called Big Design Up-Front. Instead, only a big picture of the proposed solution, as an experiment with flexibility in mind.
🤔What are we going to build?
At this point, you must make a decision about what kind of software are we talking about.
- Is it just a web application or involves any mobile or desktop deployments?
- Does it need physical tiers or just a monolith?
- And what about data?
- Can we foresee if it will be an intake-intensive system or on contrary a read-focused solution?
- How will be the communication with external systems if any?
The divide and conquer paradigm is always here to help; so start by cutting the bigger pieces.
🚩Physical and technological tiers
Almost any software system is composed of three complementary actions:
🧑🦱 Interacting with the user
🚚 Processing information
📦 Storing data
Any of them can run on the same machine or different machines. Is up to you. Nowadays the three tiers architecture is a common approach to any line of business solution.
3️⃣ The three-tier architecture
Before you jump right into the three-tier architecture, make sure you need them all. Think carefully about whether your solutions need all three different tiers in the stack.
Obviously, this architecture has great long-term benefits for any complex system. By developing and maintaining each level as independent modules on separate platforms, you could evolve any of them without affecting the solution as a whole.
And since technology (and user needs) doesn’t advance at the same rate, it might be possible to modernize your front-end by relying on your trusted and beloved database.
🧑🦱 Presentation Tier
The very top layer that interacts with the end-users. Most of the time is a web application executed in a browser. But, for sure, could be a mobile, desktop, a CLI application, or even all of them.
🚚 Application Tier
Contains the business logic and is in charge of validation, transformation, and main data processing. Could be composed up of one or several processes called services.
📦 Data Tier
Here is where the information lives. Data is kept on file systems or databases of several kinds; being transactional and documental the most widely used.
🏛️ Architectural patterns
There are decisions to take in every tier, with no silver bullets or correct answers. To help you with some of those choices, you can rest on proven and named solutions: we call them patterns.
As always, before choosing or even knowing the existence of any pattern you should understand carefully the problem you have to solve and the user stories you are going to fulfill. Slice them horizontally to get a glimpse of the involved technologies and then slice them again vertically to narrow the scope.
But hey, you are here for the patterns, so here we go:
🪨 Monolith
The tier is developed and deployed as one, with the benefit of ease of operation and less overhead.
On the other hand, any minimal change requires a full deployment. And if some feature needs a boom to scale, then the whole tier will be scaled at once. Obviously, all the codebase of the tier must be written on the same technology.
🏪 Service-oriented
Is a refinement that allows to develop and deploy a subsystem of any tier independently. Maybe a functional subdomain (🌮 vertical layering) or a technical abstraction (🥪horizontal layering).
Is a cost-efficient starting point for complex and long-term evolutionary situations.
📡 Event-based
When some features are more expensive or take longer to complete, you can scale and improve the overall system by taking an asynchronous approach.
In this particular scenario, some processes will be executed at a later time, allowing the system to run without waiting for a slow request to finish.
On most web frameworks this is included as a reactive event publish and subscribe paradigm.
On back end systems usually involves some kind of message queue and the application of Command Query Responsibility Segregation
In certain situations, this pattern even reaches down to the data level, suggesting the use of multiple databases specialized for command processing and query fetching.
🤖 Microservices
The ultimate evolution of this architecture generates multiple independent services each one with its own database. Being this is the critical difference with service-oriented, who share the same data tier.
You can have a microservice architecture with just a couple of small services.
But usually, you will evolve and refine your system by creating a different service (remember, with its own database) for each subdomain.
And you’ll keep refining until you end up with one service per user story; which means you have to manage and orchestrate hundreds of potentially totally different applications. But any of them could be developed and deployed at their own pace.
So, here’s a first look at system architecture and the role of software architecture. A piece of necessary knowledge for each member involved in modern and agile development teams.