The Naive View of a Rookie

How an aspiring software architect views architecture

Jay
5 min readJan 12, 2022

I first published this way back in 2014 on a WordPress blog I started to write before life happened. Reproducing it here because I think it is an interesting discussion and I want to ponder how my views have changed over the last 10-ish years.

Introduction

I am about to spend some time researching software architecture. Before I do so I want to document my current view of architecture so that I can look back in a few years and laugh at myself for being so naive. With that simple introduction, let's jump right in.

What is it and Why is it Here

At the highest level, software architecture is a document that defines how a software system should work down to the component level. It defines the technologies that should be used. It describes how and where the components will be deployed. It will lay out the protocols that will be used to communicate internally and externally. It should draw bold lines around the system boundaries so that the inputs and outputs of the system are well defined. It will provide an analysis of any complex interactions or data flows between components. Lastly, it will make to order coffee for every developer on the team. Yes, this is a formidable task. In the end, a team of developers should be able to take the architecture document design and implement all the individual components and when they come back to integrate those components, it will just work.

The Architecture of an Architecture

Deployment

One of the first things a good architecture should define is the deployment of the solution. Is the system a web application that will be deployed to the internet to thousands of users? Is it an internal business application with a thick client that will be used in the local workgroup? Is it a native stand-alone app for a connected smart car that will be deployed from a web store? Software is literally everywhere today so the number of deployment possibilities is ever-expanding. Luckily deployment seems to be one of the few items that are strongly driven by business requirements. Whether you work for a web technology company, device manufacturer, accounting firm, app house… it is usually pretty obvious what the user base for the system will look like and where they will be located because it is tightly linked to the core competency of the business.

Technology

The deployment that is chosen strongly influences the technologies that will be used. For example, it is not very likely these days to develop an application for a tablet using C# .NET (yes I know there is this thing called Silverlight but does anything support that even MS). Unfortunately, the deployment only decides bits and pieces of the required technology. There are still decisions to be made like whether to use a SQL or NoSQL database and what programming language to use on the backend. The choices are overwhelming. Case in point I googled NoSQL in an attempt to get the capitalization correct and the image below popped up immediately. Seven choices with a search of only five letters.

All the tech

System Boundaries

Once some of the details about technology and deployment are figured out it is likely time to start defining the system boundaries. This is defining the inputs and the outputs of the system. This sounds easy “the system takes in some data from the user and writes it out somewhere else”. Sure that is the basics but what about input from sensors, configuration data, oh and don’t forget all that data from the web. If your system isn’t a mashup of some kind these days it is hardly relevant. As for outputs don’t forget about logging regulatory data and tracing debugging information. Without it how will you move the blame on to somebody else by pointing to a cryptic line of text and announcing “see not my problem”.

Components

Ah, components. The thing most architecture documents don’t forget. A picture is worth a thousand words so grab your trusty UML tool and start drawing all the little boxes and the little dependency lines between them. Beware though too many boxes and lines quickly become a tightly coupled component explosion. To avoid this a component diagram better have some well-defined layers. Perhaps a service interface, business logic, and data access layer to start with. Also, I like to see some vertical layers in the picture to represent the separation of concerns. There is likely absolutely no reason why the image processing component needs to know about user management. If that is not made clear some developer will unknowingly couple the two and an unexpected line will suddenly need to be added to that perfectly formatted drawing fully screwing up the pleasing aesthetics.

Interfaces

Once the components and dependencies are defined I feel architecture should define the interfaces between those components. It could be argued that this is getting too low a level in the design and should be left to the development teams. I can understand this reasoning if the interfaces that are being defined are just the methods that each component will call on the other component. This is a short-sighted view though in my opinion. The important part of defining the interfaces is defining the data that will be passed between components. The main reason for this view is that I have seen too many times multiple definitions for the same data. For example, I once worked on a system that had five definitions for a 3D point. Yes, that’s right a structure containing three integers was defined five different times which meant there were ten different translators and all sorts of different behaviors. This is unacceptable. The fundamental data of the system should be defined in the architecture and then this data should be what is passed between the components.

Behavior

Behavior is the last piece and helps prove that the components and the interfaces are correct. This is not the behavior of any particular component but rather how the components interact during one of the long data flows through the system. For example, when a user logs in how will the credentials get from the UI to the authentication component. Then how will the authentication component get the stored credentials from the database; and finally get the results back up to the UI both for a successful login and for a failed one.

My weapon of choice for documenting behavior is the UML sequence diagram. I find that drawing these for the complex data flows through the system will shred an architecture faster than just about any other analysis. This will uncover missing components and interfaces in a hurry. It will show that data never even thought about is fundamental to the system and leave some components all by themselves with nobody to play with.

There it is, my picture of software architecture. I aspire to get all these pieces in any architecture document I write and I look for these things when assessing somebody else's architecture. As a developer any time I see a couple of these elements missing I immediately start to assess how screwed this project is.

--

--

Jay

Outdoor enthusiast and collector of hobbies that gets paid to build really cool stuff in the form of software.