DEV Community

mosbat
mosbat

Posted on

My Personal Experience with Overengineering vs. Under-engineering

Alt Text
I've been writing code for quite a long period of time now, and across different companies including my own projects, I noticed a trend in how people write code by different factors. I found moments when I was shocked with the sheer amount of code that had been written. Other times, I saw some code that doesn't look so pretty;I asked questions sometimes to really experienced Devs of why they have decided to write such simple stupid code and the answer I got was very interesting.

One of the thoughts that flashed into my mind, how do I know if I'm overengineering. Without even Googling and reading articles or books here and there, I came up with the following rules.

1. Don't create utility classes or interfaces if they will be used only in one class.
2. If you need to do more than 2 calls to achieve 1+1=2, then you know that your structure needs to be tuned down a bit.
3. Leave your code for a couple of days and come back to it. If you can't figure out what your code is supposed to do within a few seconds despite the fact that you've written it yourself(without debugger), then it means you have overengineered it.

Now let's have a look at the other corner. How do I know if my code needs extra engineering?

There are "Symptoms" that can tell you if you need to put more effort into the code:

1. You are copy/pasting code from one place to another multiple times which by the way violates DRY (Don't Repeat Yourself) principle.
2. Does your class violate the Single Responsibility principle? If the answer is yes, to what extent? If you have already begun implementing a design pattern to make the code more maintainable, then you can begin removing code that violates the Single Responsibility principle. Wait a second! Why don't we NOT add such code that violates the Single Responsibility principle at the beginning?!
- This takes us back to my above rules about how do we know if we are overengineering.
3. If you expect that your feature will require later on more features on top of it, then it would be wise to put some effort and time to keep things abstract. However, this is only if you are 100% sure that it will be further developed.

You might call the above approach as "Lazy". However, it does speed up development and makes it easier for other Devs to maintain the code if they find what they need in a single place without having to dig deep for an hour to understand the code's logic. However, the above doesn't mean that we should abandon the best practices; we should always follow the best practices.

Finally, I'd like to give an example of spots when Dev could begin thinking of creating a new class.

public class School{
//constructors, getters and setters

public float getAverageSchoolGradesFromTeachers(){
//some massive calculations.
}

}
Enter fullscreen mode Exit fullscreen mode

The above scenario is one of those scenarios where it's a bit of a gray area if the code is violating the Single Responsibility principle. Imagine that this class is part of a larger application called TownCRM made by the government to track progress of 100s of departments. The only thing that they need is the average school grades of the town and nothing else from the School department. Here, at this point, you can if you like to create a separate barrage of classes to handle all the potential scenarios and add utility classes all over the new package to get the school average grades. However, can you think how much confusing it will be if someone else will open your code and gets stuck not understanding what the hell is going on if the code is supposed to return 1+1=2, but it's returning a plethora of objects that eventually give the same result? The Dev probably spent hours to change a single line of code for a component that the business can't really market it because the end user doesn't care about how the code is working but rather if they get the expected result.

Conclusion, there is no bullet-proof way to find the balance. However, what I've written above is my personal opinion about how we could maybe achieve the desired balance between robust code and code that is easy to maintain.

If you have any comments or thoughts, I'd be glad to hear them.

Discussion (0)