Inspired by a video by Mattias Petter Johansson — I’d like to share some thoughts on five main phases in a lifecycle of a software I’ve seen.
1. Adding new features
A feature is something that works.
Well — if you think about it- making something work is the most important expectation from a software developer. There are business requirements, there is a certain budget/time allocation and … the code should work. Surprisingly or not — this process will repeat over and over again in every software project.
Your Client loves new features. He can know nothing about the code, but he will tell you perfectly if the requested feature works or not. Usually, once one feature is done, Client will ask you to build another one, the sooner the better.
There are certain situations — when your main and only focus & priority should be to make the code works:
- hackathons, programming contexts based on time
- simple prototype
- we’re interested in one-time calculation and getting the result instead of running the software for a longer time
- proof of concept
- complex algorithm you’re not even sure you’re able to solve and will run in a reasonable time
Why you should not only focus on features when writing a business-oriented code?
Code that works is actually a relatively easy goal to achieve. In the long term there are multiple things that can go wrong when focusing just on adding them. In general — bad architecture incorporated due to heavy deadlines — can and definitely will have impact on the team’s velocity to add features in the ne next iterations.
2. Rewriting from scratch
Actually a cost of a house is often a good comparison versus the cost of a software application.
There are various types of buildings: a dog’s kennel on one end and a royal palace on the other
— but there are some similarities in those two areas.
Netscape’s history explained by Joel Spolsky shows that it’s not always a good decision to rewrite an application from scratch. By the day Netscape’s team made this decision — they were industry leader and nowadays… nobody uses their web browsers — see diagram below:
So why people do want to rewrite from scratch?
First of all — one thing that non-technical people do not realize from the very beginning — is that a developer spends around 70–80% of their time reading the existing code and only 20–30% writing it. These numbers can differ in various projects, but they’re mainly true.
Developers are also very optimistic when estimating the complete rewrite of an app that already works. The reason for that is they usually are not taking into consideration the time spent on fixing bugs and trying/replacing different architectural approaches on the way.
It’s also much easier to reason about the new code compared to thinking about the complex codebase we have in the code’s repository. It’s usually a good time to play with new software tools:
Why it usually looks tempestuous, I’ve seen only few situations in my life when the complete refactor was absolutely necessary. I’ve also seen much more situations — where there was a business decision to rewrite the existing code and in the end it was a bad decision.
3. Code refactoring
You can be shocked how good the bad code is. Instead of rewriting it from scratch and therefore throwing away tons of money — you should consider gradual code refactor.
One good think about your current code is: it works. It has been tested by many users. While using the gradual code refactor — your codebase is ready to be shipped to production with almost no delays. There can be few days difference, but in general situations — you’re ready. When you compare to a rewrite scenario — you will find the main disadvantage of the latter being the need to wait until the very end of the process so you can have your system functional (as it was before, just got some architectural problems).
Once you think your rewritten code’s ready, your testers will probably find new bugs in it, business team will get angry. Even when it’s bullet proved, it might be the case your users won’t be able to use it’s interface as it’s new for them and nobody trained them how to do it. So please use rewrite wisely
4. Removing features
Your team has done a great job adding features and keeping the code clean in the 10th, 20th, 30th and 40th Sprint. There are now tons of working features in the application. The question is — are the users using all of them? Is it easy to add new features to that codebase?
No matter what architectural assumptions you’ll make — it will be, eventually — more time consuming to add new features to the project. If you’re building a front-end application — it will also mean — your JS bundle can get heavier as the times goes by and your users will feel it.
I’ve been many times in a situation an older codebase was raising a warning saying:
We’re terribly sorry, but the feature … is deprecated in the version x.y.z
This warning can even translate into an error as the times goes by.
As it can be difficult to use the code that will have some features removed it is even much more difficult to erase that code. In order to keep the code clean — you might need to remove application layers and abstractions. Usually by that time it’s useful to have automated tests in place, otherwise you’ll end up having too many regression errors. Having unit tests done well will save you a lot of time and you’ll feel confident about what you’re removing.
Good example of this rule being implemented is Project Eraser — which is mainly focused on removing features from Chrome that are no longer valuable.
5. Distillation into a new product
Gradual code refactor and removing unused features is not always the best way for your users. Sometimes it’s much better to make sure which feature is the mostly desirable one and build a completely new application to focus on this feature. And only that one. You don’t necessarily need to kill your old product. There are many case studies when building a new application worked perfectly well together with keeping the old, legacy code:
1. SalesForce, Force, Data, RelateIQ:
While having a great ecosystem of sales-focused companies and focusing on their day-to-day problems, SalesForce company found new issues companies are having. Instead of adding features that address those problems into their main, core-flag product — company came up with Force.com and Data.com. There was also a well heard-off acquisition of a company named RelateIQ (now it’s known as SalesForceIQ) — with it’s focus on understanding relations with customers based on data analysis algorithms. While many people tend to use RelateIQ over SalesForce because it was just much simpler for them, eventually they can use the power of a large-CRM and an easy to adapt tool in front of it.
2. Fog Creek, FogBugz and Trello:
Most of you have probably heard of an web application named Trello. But its history starts with another product named FogBugz — which was one of the first and commonly used project management applications. While it was getting its popularity — many people complained it’s difficult to teach non-tech clients to use FogBugz. This is why it got a new agilish view. While FogBugz was a perfect tool for managing technical projects, for non-tech people a simple list of to-do lists is fair enough. So the Fog Creek team decided to write a complete new tool and name it Trello. It’s worth mentioning Trello has been eventually acquired by Atlassian by $425M. So it was a good decision.
3. Facebook and Messenger:
There are some people that finds Facebook a really distracting thing. It was cool to find my friend online and build my personal database of them, but these days I’m using more and more Messenger over Facebook. It’s because I want to share my life moments with fewer number of people and don’t want to be exposed to dummy videos, ads and never-ending discussions in comments. But this is no problem for the Facebook team. For many people like me they’ve extracted their chatting tool into a completely new application and it just works really cool. In April 2017 Messenger has reached the 1.2B active users count while the main Facebook app has 1.74B active users. So there are more people like me for sure.
To sum up this article:
- Learn how to write code that works
- Refactor over rewrite for most of cases
- Be prepared to remove features
- Eventually distill code into a completely new sub-product.