I love deleting code. It’s one of my favorite maintenance tasks. Every unnecessary line of code in an application weighs on my mind like an unpaid bill. I feel a sense of glee when I get a chance to delete a feature we don’t need anymore. Every line, function, class, and feature has a cost. It costs additional time to maintain. It’s more lines to read through and debug. It’s more places where something can go wrong. Unnecessary code is sometimes referred to as technical debt for a reason. The longer you avoid paying it down the more it will cost you in interest.
I worked on a large legacy code base many years ago where the practice was never deleting code. Out of date documentation, old forked versions of libraries, and irrelevant bash scripts littered this project’s repository. The original developers weren’t around anymore. Whenever I had to fix a bug it would always involve several wild goose chases. I’d start tracing and grep’ing through the code trying to determine where the bug was. Eventually I would realize that the entire set of code I was working through wasn’t called at all. Or at least I thought it wasn’t called. I was never completely sure. There were no tests at all so I never had any confidence what I was changing would actually work.
I was afraid to delete the code for fear of breaking something. Deleting unnecessary code, documentation, and tests is part of good project hygiene. These dead bits must be cut out and removed. That and a good set of regression tests help avoid the fear of doing more harm than good.
While there are cases where it’s obvious and necessary to remove things, sometimes it’s hard to let go. We’re proud of the code we write and the applications we build. Deleting a feature can feel like you’re negating your efforts or declaring it worthless. You might also feel the need to justify the existance of features that are no longer needed. You spent all that time designing, building, testing, documenting, and maintaining it. How can you give all that up? This is similar to the sunk cost fallacy. It doesn’t matter how much effort has been expended on building something. You have to choose objectively. Ask yourself, from this point on, does it make sense to keep this code around anymore?
I’m currently faced with this dilemma. I built a tool for orchestrating the deployments of many different applications and tools across dozens of machines. I’m really proud of the design and implementation. It automated a very painful process at the time I built it. We recently started the process of switching to Chef for managing virtual machines. I realized we could replace all the custom deployment code with a few Chef cookbooks.
This would have a lot of benefits. An open source tool like Chef is going to have been tested very thoroughly. In addition to whatever unit and regression tests come with Chef it will be tested in real world scenarios millions of times. Chef is going to be maintained and updated by the community. We’ll be able to benefit from the hard work of all those people. Though we would still have to write our own cookbooks for deploying our applications all the glue code from my framework would be replaced by Chef itself. This would seriously reduce the amount of code we’d have to maintain for deployments. Another benefit of using a well-known and widely used tool like Chef is that all the common problems are solved and only a Google search away. When you hire a new person it’s possible they already have experience using it. This won’t happen with my custom solution. I’m not going to find answers on Stack Overflow about my custom deployment framework.
One possible downside of switching to a non-custom solution is that it might not fit our needs as well. While I don’t have much experience with Chef it seems extremely flexible. Pretty much anything you can write in Ruby you can do in Chef. There aren’t any more downsides that I could think of aside from the cost of having to learn a new tool. This is mitigated by good documentation, another benefit of using a well-known, popular tool. There’s also the many articles and online guides that have been written by third parties.
What seemed like a bad thing, throwing away a framework I had spent a good chunk of time developing, turned out to be an easy decision. There are just too many reasons not to make the switch. We have to be ruthless. We can respect the effort that went into building the old while we make way for the new.