Wednesday, April 22, 2009

Over-Engineering by Default

When creating large systems, I tend to over engineer everything. I’m not sure why, but I hate casting parameters to their native type and I absolutely despise writing the same line of code twice. For some reason, I think that everything has to be generic and abstracted to the atomic level. I wish I could just tell my brain to settle on using ‘object’ sometimes and move on. Instead, I over cook basic concepts and the result is a fine-grained architectural nightmare.

Oddly, I tend focus more on the idea of over engineering my solution long after things have been working fine. Clearly I’ve recognized a pattern somewhere along the way, but it drives me crazy when I can’t lock it down to a solid set of patterns.

Today I struggled with something and considered multiple implementations. Each seemed to have it’s own pro’s and con’s, but nothing has jumped out as the “correct” solution yet... I’ve wasted pretty much a whole day today trying to work in some pattern with a base class template that accepted a generic <T>. I was noticing that certain classes always dealt with another type of class. I changed a lot of code to get it to work, only to run into a brick wall at the end. The main problem that I was overlooking was that my solution is a multi-project solution and there was 1 simple class that resides in a higher level assembly preventing the whole thing from gluing together.  :( I just couldn’t figure out a good way around it. I finally realized that I was spending way too much time on it. Worst yet, I wasn’t even really going to gain a lot from the change anyway, other than a big “cool” factor. Whatever! I’m going try to sleep on it and hope that it will come to me over night.

Another one of my big struggles after all these years of coding is deciding when to use an abstract base class and when to use an interface. This is another one of those things that I tend to rethink after my solution has been working for an extended period of time. Unfortunately, I’ve not found the golden rule for deciding when to use an interface and when to use a base class. I know that there is a lot of information on the web (here’s MSDNs’ idea), and pretty much every developer (except me) has their own “tricks” for determining. For me, it continues to be a struggle and I have to really think both concepts all the way through before deciding.

One trick that I use is by determining if an object has the characteristics of something, or if it actually is that something. I always try to figure out if my object (interface or class) has any shared logic or classes as well. If there is one thing that all instances should have, I try to engineer toward a base class implementation. Sometimes that doesn’t work, so I go back and try to code it as an interface. I’ll go back and forth with each until one makes the most sense. :( Clearly I’m missing something here... I should be way beyond this after all these years! This sounds like Programming 101 crap! I yell at myself each time I catch myself doing it.

Truth is that I do this all the time in my profession, and I hate it more and more. In the long run, I usually always get that glorious “AHA!” moment, but it’s always a long puzzling road for me... I guess I’ll keep over engineering everything until I smarten up a bit. (?)

Simple concepts should not require over engineering; it is a waste of time. Sometimes it works out great. But other times (like today) I wind up just making things worse and put myself back a few steps. I’m sure that I’m overlooking an obvious pattern here. If my dreams don’t show me the answer before tomorrow morning, I am going to simplify everything back to the basic that I had this morning. :(

Oh yeah, deadlines suck too!


Tim Hibbard said...

Interfaces are nice because they are so lightweight and a class can implement multiple interfaces. But with the increase of CPU speed and RAM, who cares about a couple bytes here and there.

I try to use abstract base classes as much as possible. Sometimes it can get to be confusing if you have several layers of abstract base classes, and that is when I would use interfaces.

Tim Hibbard said...

Oh, and I do the exact same thing with over-engineering. I spend hours avoiding multiple instances of similar code!

Mr. Abakumoff said...

Who uses over-engineering? Beginner programmers who do not understand the OOP concept properly. Persons who think that if they use patterns in the code, then the code becomes better. No, Luc, your code still sucks even if you use design patters. The good news for you are - the practice will make you better programmer and you will not think about such things as interfaces vs abstract classes and you will not publish such a posts. :P

Luc said...

Tim - I'm a big fan of both and drawing the line between the two has gotten a lot easier over the years, but I still struggle when I try to over think things. :)

Sergey - Thanks for your wonderful advise, compliments, and over all ruskie dickishness! This could classify as a "Русский Брат Fail"! :)

Mr. Abakumoff said...

How is what I said is related to my nationality? Luc, this is the bad tone to point to the unrelated topic during the discussion, especially if you don't have any thoughts that make sense.
So..your reactions seems as "stupid US screwed up again"

Igor said...

Guys, I thought Cold War is over, isn't it?
I wonder what you meant by "Русский Брат Fail"...