There's an interesting paradox in software development. If you boil it down to its essence, a program is a set of binary decisions. Things are either true or false. But in reality, building information systems is rarely about being right or wrong.
The reason for that is that most applications operate in a changing environment. If you're starting a business, the MVP that helped you get traction might not be suitable for large-scale use. If you're a marketplace, a payment workflow that worked for a given currency might all of sudden fail when you want to expand to other regions. If you're a micro-blogging platform, the moderation features that were right for 100,000 people might not be as compelling for 100 million users.
Unless you're writing code for a closed system that has minimal variations (video games used to be like that, but not so much nowadays), then you're writing something that is extremely likely to be wrong in the future. It is a natural consequence of rapid changes in technology and markets. So, writing software ends up being about making tradeoffs taking into account our current situation and the trends that we are seeing. Here, I'd like to suggest three questions that can help pick options, regardless of the problem you're trying to solve or the tech stack that you are using.
How much bandwidth is this giving us?
The question of bandwidth is not a surprising one, and this is often what we focus on when we say that a solution is right or wrong. But the idea here is to push things further and try to give a rough estimation of when the implementation might break.
It's not about doing costly calculations for weeks to know precisely at what number of users, or files your system will start failing. But it's important to get a rough idea of the capacity you're building. Sometimes it's easy - I once worked on a system where years were literally written in the code, things would break past 2010 - and sometimes a ballpark figure will suffice. Keep in mind that there's no right or wrong answer at that stage. You just need to set some expectation with regards to the time you think you're buying.
What's the cost of implementing this?
As said in the previous paragraph you need to see the act of delivering a solution as a financial transaction. You're buying time until the market forces you to adapt or change your product. So you need to evaluate the cost of implementation to get a better understanding of its value.
There's no silver bullet here because it needs to be balanced with your actual position. If you're starting a business, you could pick a microservice architecture which would give you years of bandwidth right away. But this is probably going to take you a few months to get it right. So if you're still in the process of validating your idea, then it's probably enough to spend a week building a prototype that will break in a month. But if you're already having thousands of people coming to your service every day, and dozens of existing capabilities to support, then you need to invest enough in your next feature so that you don't have to refactor it for a while.
What will be the cost of replacing it?
The third and last question is about anticipating the inevitable re-write of your feature, service or product. A reason why micro-services are so appealing nowadays is that they try to tackle that problem by making systems easy to change by design. However, you can still prepare for the refactor with a few good quality practices and by isolating components in your code. For instance, I'm a huge advocate of starting out with an API in the backend as it forces you to define the boundaries of your application and makes it easier to change parts of your application in the future (you only need to keep the input and output of your endpoints).
The bigger picture is that you need to add the costs of refactoring to the costs of implementation. The most significant benefit is not that it will make you change your architecture. It's that it will force you to think about what the future you will need to understand how to improve your solution. It will lead to having cleaner code, better documentation. It will make it easier to understand the benefits of having automated tests. It will help to see the danger of rushing a new feature through the gates, even if it would work right now.
Obviously, code can be plain wrong. But I would advise people to try to use these three questions in specs, designs, code reviews and discussions whenever possible. Steering away from the assertion "this is not correct" and talking about the tradeoffs will help facilitate communication and foster a healthier debate for the team and the customers.
Squadlytics is a productivity analytics platform for software teams. Try it for free today.
(Photo by NeONBRAND on Unsplash)
Enjoyed this post? Get more like that in your inbox.
Scaling small is a weekly newsletter talking about doing big things while staying lean.Subscribe to Scaling Small