An anecdote about overengineering
Published on Saturday, 25. April 2020Overengineering is probably the way I most enjoy being unproductive. There is something deeply satisfying about writing 100 lines of beautifully designed code to reduce 5 lines of code to one in another place of your project. Obviously, this behaviour, as fun as it may be, doesn't always make sense.
But the transition where engineering becomes overengineering is blurry. Often, something that looks like overengineering in the short term, saves a lot of time in the longterm. There's a tradeoff to be made between the time you put into structuring your code and the pure functionality you want to accomplish. It isn't helpful if you just focus on the functionality but need to rewrite your systems every two versions because it breaks constantly.
To better think about this topic, I define overengineering as engineering for its own sake. In the end, the most important thing you want to accomplish is to solve the problem you set out to solve.
This might sound obvious, but when you start working on a solution and get lost in your engineering, this becomes harder to see.
For example, when working on War on Prehis, we serialized the data for balancing the enemy waves in JSON files. Instead of using the existing utility functions in Unity, I decided to implement a JSON parser myself to apply my knowledge of context-free grammars.
Obviously, if you just want to finish the game, that's a stupid thing to do. It took me about a week and the version I came up with didn't work. This is an extreme, yet typical example of overengineering and how I fall into its trap.
There is an easy way to prevent this from happening. It consists of asking yourself three questions before starting to work on your implementation: Who is it for? What is it for? How can I simplify it?
This post is written in the context of software engineering. But in the end, this line of thinking is not just applicable for writing code but is a general guideline for any design. Always keep in mind what problem you want to solve and how you can simplify your solution.
This means something that at first glance looks like overengineering from the outside might be perfectly reasonable to do. If you want to learn how parsing a context-free grammar works, implementing a JSON parser is a great exercise. Just don't do it, if you should focus on balancing your game instead.
To take the three questions to a test, let's look at another example. Last Christmas, my dad gifted me the book Year of Wonder, which presents one piece of classical music per day. This makes the book quite huge. As I didn't want to take another book like this with me while traveling, my first instinct to solve this was to transform it into a web application. Within seconds after having the idea I had convinced myself that this would be a great project to work on. I could double down on web design with a simple and obvious use case, build something I would use on a regular basis, and maybe even earn some money from it (given the permission of the author). Fortunately, I had these three questions in my mind.
Who is it for? First and foremost, it's for me. I didn't really care about solving a problem others had.
What is it for? I don't want to travel with another book that doesn't fit in my backpack.
How can I simplify this? I could just buy the ebook version.
Well, that's exactly what I did. And with the amount of 5€ I finished this project in less than 30 seconds.