I have not written for a long time on this series. Circumstances, lots of work for other projects and the unfortunate events that happened linked to Covid-19 have thrown me back. But I am back now and ready to talk more about Software Architecture, its concepts and best practices.
To put us back in perspective, last post was dedicated to introducing the topic and this series. Today's post will be dedicated to define what is architecture and define its goal.
|Introduction to the series
|What is architecture?
|Introduction to the concepts of design and architecture in software and why they matter
|Starting from the bottom
|Coding paradigms and why they affect our architecture
|5 architecture design principles to always have in mind when designing software
In software development we often distinguish two critical concepts that influence different levels in the software: architecture and design. In practice, we often refer to architecture as a high level principle such as using using microservices, authenticating using this kind of flow or another, or more on a high level organization (efficiencies, maintenance, cost, etc.). Those macro architecture principles would then provide guides for the design, referring mostly to the specific decisions made by developers while building/putting together the piece of software. Although for most of us this picture is clear in our mind, it is unfortunately our first conceptual mistake, and lesson :)
To illustrate our point:
Think about an architect planning a house: the architect will need to define the high level plan (walls, materials, etc.) but ultimately, his decisions will influence and define the position of power switches, lights, electrical cables and from which wall the water intake would be located. Macro architectural decisions affect and define lower level design decisions.
Similarly to a house architect, a software architect will define the high level structure, taking decisions that will not only influence, but also strictly define several low level designs. We decide to take a microservices approach that will influence how we communicate between those, structure our code and name our variables & files. As such, we need to consider architecture and design as strictly similar concepts. Software Architect professionals should therefore not limit themselves to high level concepts, but also understand how their decisions will influence and directly define low level design decisions. Software Architecture and Design are the same.
And all those decisions? What are they meant to achieve? What is the goal of a software architect? According to Robert C. Martin:
The goal of software architecture is minimizing the human resources necessary to create and maintain the required system
What does it mean? It means that the quality of an architecture will be defined by the amount of work the related software's creation will require but also what maintenance will it require. I am sure you can already think about one of your project, in which bad architectural decisions lead to hours spent where they shouldn't have been spent therefore costing more to your company, your clients and ultimately your own sanity. Second lesson, software architecture quality can be measured by objective metrics.
In order to make it clearer, let's exemplify it using a fictional case:
Imagine a company that is currently completing a project with a team of 8 developers.
Those 8 developers cost USD 800K a year and managed to deliver a product of 1,000K lines of code. We can define their monthly productivity as 1,000K lines of code / 8 devs / 12 months = 10.5K lines of code per months per dev at a cost of 80 cents per line of code. Not so bad in my opinion!
Now let's imagine: Our devs integrated many third party libraries too quickly because they were pressured by deadlines and did not think well about some crucial part of their architecture. After a while, some crucial security issues arise from those libraries, and it's time to update them. Problem: The devs, pressured by deadlines, didn't take the time to integrate the library properly for example in a separated service clustering all the functions using this specific library. They simply called the library directly whenever required directly from many services spread across the software. We all know the complexity arising from this kind of tedious upgrades. In order to upgrade and maintain those integrations that are critical for their software, the dev team needs to grow by assigning a few devs to make sure any third party libraries integrated are maintained up-to-date and integrated properly.
Let's go back to our numbers:
We now have 10 developers for a cost of USD 1,000K a year.
Two developers are assigned full time to make sure to maintain integration and do not produce new code, they only work on maintenance tasks (bug fixing, updates, etc.). Our devs monthly productivity at N+1 is therefore 1,000K lines of code / 10 devs / 12 months = 8.3K lines of code per dev per month at a cost of 1 USD per line of code. A little worse than before.
As you can see, productivity per dev dropped 21% and cost per line of code rose by 25%. Not great. And this is just the first year. As we all know, those kind of behaviors and bad decisions are usually rooted in the company DNA. It will probably get a lot worse before anything will be done by the higher management that will start to witness immense increase in dev numbers, salary paid together with a decrease in productivity (new features, extensions, etc.).
This is the definition of a bad software architecture. A great architecture would have limited the time and resources needed to perform maintenance, bug fixes, updates but also would have kept a smaller team more focused and overall would have delivered greater productivity (at least in theory).
Most of the time in software bad decisions leading to bad or not so great architecture happen when devs are:
1) too confident about their decisions
2) rushed under crazy deadlines
It is essential that software developers and architects take their time, think their decisions through and make sure their current decisions (that will probably deliver the intended purpose in the short term), will not influence badly their project in the long term.
We all lived situations in which we had to come back to our code, months down the road, in order to change this or this part because of our bad decisions (rushed through to respect deadlines or without consulting our peers). It is tiring, frustrating and difficult sometimes to get back the mindset and momentum we had at the moment of built.
In order to tackle those issues, organizations and developers need to understand and recognize that their decisions might not be the best ones. We need as professionals to understand the implications and tradeoff we make every time we take a decision on software architecture.
Is respecting this deadline more important than really thinking through how I structure my micro-service and maybe spend the next two days structuring it, testing it and making sure it is well integrated within our structure?
Rather than creating monolithic components to go fast, I will rather take some time and separate functions in separated services.
Should I really consult my colleagues when deciding upon going with this kind of data structure for this particular object? Going one way will be easy, the other way will signify building more code an ultimately delaying other things I would like to tackle for another months. Should you kill reusability for the sake of time?
All of those moments/questions will ultimately take a few hours off my planned schedule, sure, but in the long term, a serious look at the quality of my software, the time needed for maintenance and the resources spent on it will give our clients and users satisfaction.
Don't forget our two insights in today's article:
1) The quality of our architecture is measurable objectively with the time and resources spent on building and maintaining it
2) It is better to think a lot on the quality of our software and go slower than the opposite
That's it for today! Although the article was short, I believe it really reminds us all that, when it comes to Software Quality and Architecture, every decisions count both on Macro and Micro level and we need to be 100% aware that quality now will influence quality in the future.
In the following article, we will take the time to learn/situate the great coding paradigms that have a strong influence on how we practice software architecture.
Make your software provide more smiles than tears!
I am a partner at MMPG Consulting, a firm active in the custom software development industry in the Spanish and Swiss markets.
You can add me on LinkedIn or shoot me a DM if you want to discuss specific topics, your software or an idea you want to implement.
I am writing this series while reading books about software dev, the ideas and principles exposed will be taken from those books. In those articles I will sum them up and discuss concrete examples. I am not introducing new ideas or principles about software architecture. Essentially because my thoughts on it do not, and will not, introduce a paradigm shift or introduce ground breaking architecture principles (...who knows!).