Well, perhaps minimalism is not the right word for what I mean, but it reflects a very important characteristic: simplicity. As a software consultant I often find myself moving from project to project and tackling different kinds of problems. But among the most common of the problems it’s over-complexity.
Complexity is the worst enemy of a software project. And it’s even worse when complexity is not even required to build the respective solution. The latter I call viral complexity because it spreads like a deadly virus killing team motivation, product quality and adding unexpected costs for future development and support. This is the sad death of many software products.
How it all starts
In most cases it all starts with a blind rush. It’s a simple requirement, a small project and needs to be ready yesterday. So we’re looking for the simplest solution that will work given our situation. We do a quick hack and voilà! The whole thing is up and running, ready to be delivered. We have little time to congratulate each other because the business comes in with more requirements. We’re supposed to be agile and embrace change so we adapt our hack to include the new changes. But again, there are more and more and more. Soon enough our hacky solution becomes a major point of complexity as we’re not merely adding features to a project, but we’re adapting a hideous hack to support more and more features for which it’s not adequate anymore.
Hurry, hurry, hurry!
By now the business is happy with the results and learns that giving just a small set of requirements for implementation upfront works great. Agile really works! They also congratulate themselves for putting pressure on the development team for releasing something quickly. What they don’t know is they’ve built a long queue of technical debt which, like all debts, is expensive. And they don’t even know they need to repay it.
The requirements keep on coming in and the developers struggle to implement them. Some never get done, others take very long. People outside the project will soon start wondering what’s going wrong. But do they really want to know the truth?
The truth is the project started with technical debt, that the quick hack was intended to be a short-term solution to a more complex and time-consuming one. This means that as soon as the initially simple product was deployed in production, the project should have started from scratch. That didn’t happen and created a huge pile of issues that no one is willing to take the blame for.
Now it may be too late or too expensive to start again. It may also be the case that the business doesn’t really understand all this and plainly blames the developers. And so they should!
The best cure is prevention
When the business comes in saying they need a product and they need it fast and when they say it’s something simple and should take a very short while and it’s a key thing for the entire company’s business and needs to get done — it’s not the right time to panic, it’s just the right time to say no. It’s just not possible to do it without many side effects and if the business is ready to pay for the technical debt, they’d better be ready and they really need to understand this is not just developer fuss about something that not beautiful code or unprofessional. It’s just expensive.
When you want to buy a car and don’t have all the cash, you take a loan. But you know the loan comes with interest and in the end you’ll be paying more. That’s acceptable if you really need the car now and can’t wait to save the money and then buy it. The same way the business needs to now that soon they’ll need to start paying for the technical debt before adding some more features to the product.
Lack of repaying the due technical debt leads to greater complexity as adding more features to an inappropriate structure is complicated. The more features are added the more complex it becomes and harder to understand.
Start simple, keep it simple and self-explanatory
A good solution explains itself. It doesn’t require documentation, experts, expensive consultants or even code comments. Some will say these are just words and it’s easier said than done. I disagree, it’s all in the attitude.
First everyone needs to understand that we’re better off adding fewer features, but making them part of a simple and self-explanatory system. It’s always better to have a simple and stable product than a clunky one.
As more features are added, keep refactoring the system so it adequately grows to house the new functionality. If you need to build a skyscraper, it needs a solid foundation. If you start with a tent, you can’t evolve it into a skyscraper without refactoring the foundation several times. This is part of the development cost so we all need to live with it. It’s just common sense.
Think before you write code
Ask yourself before committing to a solution: is this simple enough for a newly joined developer to understand? Is this the standard way of doing it so that other developers would easily understand what we need to do? Are we using the right tools and technologies for the job?
Don’t just accept something because it works. If it’s not simple and straightforward, it’ll just bite you back soon enough. And although this is not a functional feature and no one will actually pay for it, you must make sure the system is covered by tests that not only certify its stability, but, most importantly, documents its behaviour.
Will we ever learn?
This words have been said over and over again for the past decade and still I find projects making these mistakes. I can’t stop wondering why are we never learning?