I've spent a lot of time reading different books about "good design", "design patterns", etc. I'm a big fan of the SOLID approach and every time I need to write a simple piece of code, I think about the future. So, if implementing a new feature or a bug fix requires just adding three lines of code like this:

if(xxx) {
    doSomething();
}


It doesn't mean I'll do it this way. If I feel like this piece of code is likely to become larger in the nearest future, I'll think of adding abstractions, moving this functionality somewhere else and so on. The goal I'm pursuing is keeping average complexity the same as it was before my changes.

I believe, that from the code standpoint, it's quite a good idea - my code is never long enough, and it's quite easy to understand the meanings for different entities, like classes, methods, and relations between classes and objects.

The problem is, it takes too much time, and I often feel like it would be better if I just implemented that feature "as is". It's just about "three lines of code" vs. "new interface + two classes to implement that interface".

From a product standpoint (when we're talking about the result), the things I do are quite senseless. I know that if we're going to work on the next version, having good code is really great. But on the other side, the time you've spent to make your code "good" may have been spent for implementing a couple of useful features.

I often feel very unsatisfied with my results - good code that only can do A is worse than bad code that can do A, B, C, and D.

Is this approach likely to result in a positive net gain for a software project, or is it a waste of time?


  good code that only can do A is worse than bad code that can do A, B, C, D.


This smells to me like speculative generality. Without knowing (or at least being reasonably sure) that your clients are gonna need features B, C and D, you are just unnecessarily overcomplicating your design. More complex code is harder to understand and maintain in the long run. The extra complexity is justified only by useful extra features. But we are typically very bad at predicting the future. Most of the features we think may be needed in the future will never ever be requested in real life.

So:

Good code that can only do A (but it is doing that one thing simply and cleanly) is BETTER than bad code that can do A, B, C, D (some of which might be needed sometime in the future).
