Architecture is all about big-picture structure and organization, so it’s no surprise that software architecture design is the core of any successful software solution.
Imagine building a bridge today. Stability, resiliency, and agility all require intentionally designed structure.
And just like building a bridge takes more than pushing piles of cement and steel across the ground, making sustainable software takes much more than slinging code.
Whatever you do, there’s always a structure to your software. If you don’t deliberately design it to last, it’s no secret that it’s just a matter of time before it crashes.
To make matters worse, unlike other types of architecture, your software has no physical constraints that force you to follow physical laws. And your structural and functional code often get mixed up, making it hard to set up and maintain structure.
And therefore, software architecture design is deceptively tricky.
This article will look at an essential part of designing software architecture and how to keep yourself safe. In addition, we’ll talk specifically about how easy it is to fall into the disastrous “alphabet soup” architecture that’s so common today and how you can do better.
You need to know a lot about the nature of change in software systems over time, your specific system’s needs, and the specific technology in play to make sure your design is effective, supple, and efficient.
For example, a lack of a service structural taxonomy and governance over your software architecture structure means junior developers can add scores of services like sprinkling cheese on spaghetti.
It may have looked tasty to them. And it might even have worked in the short term. However, it will always backfire because too many services lead to a dangerous “alphabet soup” architecture, eventually killing your product, company, or career.
Here’s why: When the number of services explodes out of control, it drives your integration complexities to the point where your solution is so convoluted and confusing that it leads to several deadly problems, including, but not limited to, increased project costs, delays in delivery, and a defective end product that’s hard to fix.
And software is a non-linear beast. Letting structural integrity slip a bit is more dangerous than you’d think because it’s a deceptively slippery slope with an exponential drop-off.
Once you slide down far enough, you risk going into a free fall. And even if you survive, the way back takes a lot more work than building it in the first place, and there are no guarantees of success.
Want to avoid falling off career-killing cliffs? You must carefully plan the architecture of your software and check it often to make sure it stays stable and doesn’t break.
Suppose you are designing a bridge. You need to understand the underlying physics, engineering patterns, processes, and controls necessary to keep it standing. In the same way, you need to know the fundamental physics of code before you can design a good software architecture.
To start, let’s look at why we structure code.
We didn’t always structure code. In the beginning, we wrote a soupy mess of analog ones and zeros, punching holes into cards by hand to perform calculations. This wasn’t sustainable past a specific size, especially when we had to change. So, when we started using digital machines instead of analog ones, we started putting our calculations into methods. But it still wasn’t enough, and code bases started buckling under the weight of change. So, we started bundling our methods into classes, creating yesterday’s monolithic applications. The demands on our systems grew, and we suffered. Keeping up with the demands of change became hard, and the amount of work needed to change has gotten out of hand. So most of us have organized those classes into higher-level services.
And while organizing today’s stacks of binary instructions and data isn’t perfect and remains difficult, it’s better than nothing. But it’s no panacea, and the risks of degradation, disorganization, and disaster are still there, driving up the costs of keeping digital software systems alive to dangerous levels.
Here’s the problem with today’s monolithic systems: Imagine that with disorganized code, every class can affect every other class, every method can affect every other method, and every state can affect each other, causing a nonlinear atomic explosion of complexity.
Think about it this way.
Let’s say your application is one giant method with all it’s variables anc controlling lines of code. With one or two variables, it’s not so bad. Once we get to four or five, things get challenging because, in the simplest case, we have tens of states (2^4 or 2^5). Once we reach nine or ten, it becomes unsustainable because, in the simplest case, we have over a thousand states. When we get to 20 variables, we have millions of states. And at just 60 binary variables, we have over 1.1 X 10^18!
For perspective, let’s assume a grain of sand has an average size. Given how many grains are in a teaspoon multiplied by all the beaches and deserts in the world, we have roughly 7.5 x 10^18 grains of sand (seven quintillion, five hundred quadrillion grains).
Therefore, managing an unstructured system with even 60 variables is far beyond human comprehension. And I’m willing to bet $100 that even your most uncomplicated customer-facing code base has over 60 variables.
Do you want to protect yourself from this huge risk and organize your methods into classes and your classes into services?
It’s the right decision.
But don’t get too excited just yet. Your problems don’t go away that easily.
What most people need help understanding is that they’re wrestling with something similar to the first law of thermodynamics: the minimal complexity of your system is always there. You can’t destroy it. You can only hope to alter its form.
If you have one or two services, making them work together is simple. With four or five services, we have tens of integrations. With twenty services, we’re looking at millions of integrations. with as few as 60 services, your code base has more integration points than all the grains of sand on earth. And you are in a situation beyond human comprehension.
There’s a toxic alphabet soup with billions of integrations on one side. A raging lava pit with exploding state complexity is on the other side.
So, you need structure to make sure that the size of your services is carefully balanced with the number of services you have to integrate. And your only real chance is to cross the complexity chasm by walking this razor-thin tightrope while keeping your balance with a well-organized and controlled structure.
Your software requires structural integrity to survive. And it’s not enough to start with a good structure. You must keep it in check.
Like a carpenter building a house, you want to ensure your structure has integrity. Start with a solid foundation, and then make sure the house doesn’t collapse under its own weight during an earthquake or when crushed under tons of snow, depending on where you live.
The same is true for software architecture design. You need to build a good structure and then ensure it will not collapse under its own weight.
To do this, you apply rules to limit destructive options and facilitate good ones. This is what architectural software design is all about: defining and regulating structural constraints.
Refactoring code requires more than just style guidelines or OOP design principles. You must follow your structural design guidelines, or it isn’t “architecture friendly.” For example, suppose your team is changing the structure of the code base. If so, you need a list of service types you can enforce and rules for combining them. Weigh the implications of every structural shift.
This is why you require an architecture with clear service types that you can enforce as well as rules about how to put them together.
Finally, avoiding the “poisonous alphabet soup” architecture with billions of integrations is essential.
It takes more than just selecting cloud technologies. It takes more than clever code. You must follow the basic rules of software architecture, which are to write down rules for your system’s structure, make sure everyone follows the rules, and run regular checks to make sure the structure is safe.
Don’t do this, and you risk allowing your system to devolve into a convoluted and confusing architecture that is difficult to understand and even more difficult to change. Your project costs will explode. You’ll have a lot of project failures, cancellations, or delays because the structure of your systems is breaking down. This causes massive complexity, a bad end product because of architectural problems like an inability to scale or having too much latency, and more technical debt because of bad architectural decisions.
To avoid these issues, you must first understand the physics of software design and the value of resilient structures. You need to start with a viable software architecture and keep it alive as you build, change, and extend your codebase.
Best wishes and warm regards -Matt
By the way, are you struggling to keep up with the complexity, costs, and risks of owning, building, or upgrading your .NET SaaS system today?
Our tailor-fit software architecture and development services can help you avoid the “poisonous alphabet soup” of integrations and ensure your system is well-structured. We use the basic rules of software architecture, such as setting clear rules for your system’s structure and ensuring everyone follows them, to protect your products and eliminate the usual problems that come with maintenance.
With our help, you can rest assured that your system will be organized and efficient, saving you time and money in the long run.
Click here for a free 30-minute consultation to streamline your software structure, boost your teams’ productivity, and stay safe with today’s SaaS development technologies!
CTO & Founder Truthshield I'd love to help you build better products faster. Click here for my calendar to schedule some time with me. I'm excited to discuss how TruthShield can help.