There are countless ways to architect a product, project, or feature. Just like in physical structures, architectural decisions in software have a huge impact on the overall experience. With this in mind, architectural decisions made quickly and in a vacuum can lead to delivery complications later. If you don’t have a clear understanding of the end-to-end experience of the thing you’re working on, press pause and consider a few things, first.
Do you know enough about the client’s world?
PM: “We need a dashboard to view the data in our app.”
Dev: “Awesome! We can whip that up in React, no prob.”
React is a favorite among a lot of developers but is it always the right tool?
These are a few of the questions you might ask to begin to better understand your client’s world and the environment your building the dashboard in:
- Do you know where the data is coming from, and the shape it will take?
- Is there an API?
- Are we already using another framework that we can leverage?
- Who is going to view the dashboard, and from what kind of devices, over what kind of connection?
- What experience does the team have and how many devs are needed?
It’s likely that some other architectural decisions have already been made that will impact your choices for architecting this dashboard feature as well!
Do you know enough about the data and process flows?
It’s easy for a developer to take a narrow view when considering the program flow of a thing they’re working on. Making smart architectural decisions will have to account for other forms of flow.
Program flow is important but so is the flow of data within, into, and out of, the application. What about transaction flows like a customer’s process for making a purchase, or a user’s process for running a report? Have you accounted for the process flow of the business outside of this application, and how those interact with your application?
Take the time to understand the workflows that will affect, or be affected by, your software.
Several years ago, I worked on a very complex e-commerce project. The software had several different types of transactions: ticket sales, memberships, donations, gift cards, etc. There were also a variety of different internal users. Many of them were heads of their departments with different interests in the data within the system. I had been working with this client for quite a while so I felt like I had a reasonable handle on their business.
While we defined the project, one of the stipulations was that this system wouldn’t inherently be an accounting system. They’d transfer the transaction data to a different system. The head of the accounting department signed off on the approach.
Long into the development process, we started to generate test transactions with their corresponding data. At this point, the accounting department (not necessarily the manager) began asking how they were supposed to reconcile the data coming out of this system with the data from their credit card processors, banking partners, and others.
Do what now?! I thought we weren’t making an accounting system?!
Where did we go wrong?
Well, we didn’t completely explore the needs of the accounting department, and how this system’s data would flow into other systems. The manager may have been making several assumptions based on previous experience so they didn’t ask any questions. I didn’t have experience working directly with accounting departments so I didn’t ask any questions. I didn’t talk to the bookkeeper who could’ve really told me what was what. None of us had a good understanding of the impact and utility of the data coming out of this system.
In the end, I implemented a double-entry accounting system of debits and credits in the app, after the transaction system was already built. Since this was a monolithic system, it was like lifting a house and adding a foundation after the house was built. Doable, but not fun. 😎
Do you know enough about the legacy and vision?
The future is hard to predict, and you probably shouldn’t try too hard, but there are reasonable things to ask before making architectural decisions. Are you expecting an increase in team size because the company is hiring? Are you expecting an increase in customer transactions because the company is about to launch a large marketing campaign? Less reasonable considerations such as whether to use a new hot language or framework that you’ve been hearing about, should not be considered in your architectural decision making.
What about the past? Well, there’s a really good chance that you’re working on something that someone else started. Do you know why they chose Elixir, or why the app lives on Azure, or why it uses Bootstrap as a front-end library? Did anyone document any of those decisions? If they did, great! If they didn’t, you should start. There are a lot of ways to do this, and this post is already long. Just think about the future you(s) and how you wished someone would’ve written this stuff down before.
The present is important, of course, because you’ve been asked to make a thing that’ll work for the challenges of today. This is where you should focus most of your attention. You probably won’t have the luxury to make any changes to the decisions of the past. There are companies that will tolerate wholesale changes to their systems, but not many. More than likely you’ll be dealing with legacy decisions and will make the best of it. You also shouldn’t spend too much time on the future. Build what you need today in a way that is simple to understand, and as flexible as makes sense for today. Future you will be glad you did!
It can be enticing to get down to business and build with the future in mind, in the vacuum of our own understanding. That can lead to building for the wrong outcomes: problems we don’t have, for people we haven’t talked to, without the complete backstory. Understanding the challenge from end-to-end is a better starting point when making architectural decisions.