Software development is hard. Bugs and inaccurate time estimates are a fact of life. Software is too complex these days for things to go exactly as we’d like. However, developers often add to the difficulty of software development by doing certain things that make it harder than necessary. I know I have.
One of these tendencies is associating less typing with saving time. It sounds logical at first. Type less code, spend less time writing code. Yet, most of development time is not spent typing. I’d be surprised if more than 5% of it was spent typing. Most development time is understanding existing code, planning out new code, testing that new code, and debugging that new code. Reusing code for related features makes a lot of sense. It does save typing and helps out with all the other things listed above.
The problem is when code for unrelated features that looks similar is reused. It feels like the same thing because reused code is reused code right? But unrelated features are going to diverge in functionality at some point. That means that reused code is going to have to function slightly differently for each one. In the best case, every developer who touches that code is going to be aware of it and create special cases in the code. Extra time is spent in testing two features instead of one and extra time is spent by new developers wrapping their heads around the unnecessary complexity.
In the worst case, someone will not realize that a piece of code is reused somewhere because it would make no logical sense. They make changes that work for one feature, but breaks a completely unrelated feature. Now we not only have overly complex software, but we have bug ridden software.
Take reusability to another level and we start to get entire systems that are overly “generic”. In many cases this makes a lot of sense. Amazon originally had a system to sell books. It is generic enough that they can sell anything. Making a system to just sell books would have been silly if the original intention was to sell anything and books were just a starting point.
Yet, software systems can end up being too generic. The code for selling a product and the code for comments/reviews on those products are separate systems. They get tied together at some point, but a product is a distinct concept and a comment is a distinct concept. Some systems will try to remove this distinction and group them under some made up umbrella, such as saying everything is a “node” or everything is a “post”. A lot of content management systems do this.
If you’re wondering what “node” or “post” means, well that question is my point. They’re ambiguous. Overly so as to add confusion. They’re so generic that they can’t really do much for our commenting or product systems. We still have to build lots of functionality around just comments and just products. Yet if we try to wrap these distinct concepts under some generic umbrella, we now also have to deal with the additional complexity provided by that umbrella. This is in addition, not in place of.
The result is that instead of saving time by reusing code, we are spending more time dealing with the complexity of that code.
There are plenty of other examples of developers making their lives harder. We try to make things scalable when they don’t need to scale. We try to account for use cases that the user will never encounter. We try to make our code efficient, but end up adding too much complexity in order to save meaningless nanoseconds.
In all these ways, we as developers make our jobs harder than they need to be. Our job is hard enough as it is. Recognizing which of our tendencies causes us to increase our workload unnecessarily can do wonders in making our lives easier. It certainly has for me at least.