Don’t judge my Software’s Architecture too easy

Patryk Studniak
Netvise Software
Published in
5 min readMay 25, 2020
Software Architecture drivers demistyfied
All rights to 2017 Scott Adams, Inc/Dist. by Andrews McMeel

Who did it this way?! If it was me writing this code…

This is a typical reaction of an engineer watching on other’s code. Engineers, especially Software Engineers who are creating working products daily, tend to judge others because of the code style, architectural decisions, used design patterns, and so on. It happens because the same purpose software can be developed in many ways, depending on personal engineer preferences, knowledge, and expertise. But there are also other things which determine how software is designed and are not dependent on engineers at all. Those are business constraints, legal restrictions, and technical possibilities.

When reviewing a project written some time ago, you will find different approaches that were popular back in a day, which may look weird now. Sometimes you may find anti-patterns, which were concerned as good practices and after some time their bad consequences have been discovered. You can find workarounds or custom solutions drove by limitations valid these days. It’s possible to see some weird whips and code quirks that were necessary to reflect the current state of business requirements. But you don’t have to know old design patterns, you don’t have to know the old coding style and for sure, you can’t know all decision and architectural drivers of the project you are looking at for the first time. Unless…

Architecture Decision Record and Architecture Drivers Log for the rescue.

Unless you keep ADR and ADL up to date. It can solve most of the problems mentioned before. Any newcomer can immediately get answers for every ‘why’ question when looking at the code for the first time.

Architecture decision record supposed to be a document that captures software design choices that addresses specific requirement, along with its context and consequences. You can easily put a reference to a concrete record in the code. If you have this in your project, onboarded engineers instead of asking you ‘why’, will read it and understand. There are many sophisticated ways of providing ADRs, but you can choose the easiest for you and your team. If you like creating docs in the cloud, you can go for Google docs or Office365. I believe that version control systems are the perfect fit for creating ADRs as well. However, ADR not necessarily has to be maintained only by engineers who know such tools. To make it available for a wide group of users, it’s good to use popular software engineering management tools like Atlassian Jira or Confluence.

If you find ADR topic interesting, one of the github.com repositories describes ADR and its related terms in detail (https://github.com/joelparkerhenderson/architecture_decision_record).

What drives software architecture?

Software engineering is tied with architectural drivers from the beginning. This topic is as old as Alan Touring’s first computer. Algorithm implementation running on that machine was limited by hardware possibilities and abstraction layer designed to interpret the code. The code is written on tapes, red by reading head… how much flexibility do you see here?

Today, in modern software development we can distinguish typical architectural drivers. Let’s focus on them.

Business constraints

Business constraints are decisions required by businesses that must be satisfied in the architecture. Business constraints should be fixed from the start and surely influence software design and decisions made on it. Those are the hardest rules for our product. When the business constraint is defined, it should stay unchanged. An example could be a delivery date, planned budget, available resources.

Technical constraints

The same as the business constraints, technical constraints should stay unchangeable. Those are technical decisions that must be reflected in the software architecture. It’s about choosing frameworks, databases, and distribution points. Changing technical constraints can be really difficult and expensive during development.

Quality requirements/attributes.

Quality requirements are specific rules by which the performance of the software can be judged. As we all know, each software problem can be solved in several ways but the quality attributes should define which approach to choose. Quality attributes are usually written as scenarios that describe a qualitative response within the context of specific system functionality. For example, performance is a common quality attribute, but what we consider as a performance? We may understand the performance level differently in different states of the system. And each of these states should be described in a specific case. Quality attributes are described in detail in Software Architecture in Practice.

High-Level Functional Requirements, aka Business requirements

Business requirements provide a detailed definition of what the system should do. It describes all of its functionalities and features. Following agile software engineering principles, business requirements are split into epics and stories which are well defined and contains all of the necessary information for developers to work on. While quality attributes may force you to decide on specific data structures or patterns, the goal of your work is to deliver some functioning product which is an answer to concrete business requirements. You don’t need to dive too much into implementation details on the high-level project planning since this could delay the project start and cause infinite meetings loop. However it’s very important to understand business logic on an architecture decision making level to not over-complicate your code and avoid problems in the future. Understanding business requirements and designing systems based on it is deeply described in Eric Evans Domain-Driven Design: Tackling Complexity in the Heart of Software book, which I strongly recommend.

Legal restrictions

We can’t forget about legal restrictions. Those can be different depending on the country where our software may be running. Usually it treats about storing and processing user’s data. We always should keep it in mind and if we don’t have enough knowledge about the law in our target country, we should consult the whole system design with a qualified lawyer.

Does the best architecture exist?

All of the drivers mentioned before will affect the decisions made on your software design. It’s easy to blame someone for bad software architecture when you look at the old code with Today’s knowledge and possibilities.

Even that you are doing your best to provide an architecture that fits all of the requirements and assures the best quality, in the next ten years it will look like an old man trying to go up the stairs when there is an elevator. But he doesn’t know how to use an elevator since it appeared there last year!

It’s worth to mention that through all of those years, many requirements will change and a lot of adjustments in the code will be done. Not everyone will follow the best practices for writing code. Sometimes changes have to be done in a rush, sometimes engineers are not experienced enough to predict the consequences of changes they are doing.

All of this will result in many “WTF” moments in the code. However having ADR is always a good choice. Not only for future developers, but also the ones working right now on the project. They will be forced to justify their decisions and possibly the shame of writing reasons like “because of laziness” or “the whole code is crap already, it doesn’t matter how I do this” will make us work better.

So next time, before you blame someone for his software architecture, try to understand what drove the design piece of software you are looking at. And don’t be too hard for others, it’s always not only their fault :)

--

--