Mar 23, 2009

Premature Generalization is the Root of All Evil

Finally! I have now finished the first reincarnation of the new logger hierarchy for Microlog. It is a very simple tree structure that keeps track of all the created Logger objects. I choose to do a specialized tree implementation for the purpose, not a general tree implementation. Since there is no tree implementation in Java ME, it could be tempting to do a tree implementation for Java ME. When finished this could be re-used in a lot of other Java ME projects. This got me thinking about those good old days when I was a junior programmer, just fresh out of school.

I was involved in a research project with the purpose of showing the opportunities with an embedded device with an ethernet connection. The embedded device contained a simple web server that was equipped with simple CGI support. My assignment was to create a web pageswith a Java applet for administration of the embedded device. This was actually a proof of concept study. If we managed to convince our product managers about our genius invention, we would of course re-use the code for the real product. So far, so good.

I made a very ambitious design before even starting to do some coding. I can tell you, my manager was really nervous when I did not start code immediately. "No worries, good design is important for fast and good implementation. You need to be prepared really good before starting your implementation!". This was how I was taught. Anyway I managed to do a real fancy design, with many really nice-to-have-classes. I ruled the world of design and my way to fame and glory was laid out for me! As part of the design I did a very general API for the communication. General design is good, I reasoned. This was a BIG mistake!

When we were closing in on delivery date for the demonstration, I had made the general network communication. However I was not finished with real implementation, the parts that was vital for the demonstration. Anyway I was finished about 30 minutes before my project manager was going to leave for the airport, to meet the people who was sponsoring our research. I was tired since I have worked all night and my project manager was not happy. For me it was embarrassing that I was not able to deliver something that I was proud of and I was to close to the deadline. My project manager did manage to do a successful demonstration. Finally the management decided to make our prototype into a real product.

After a couple of weeks it was decided that we was going to use another low level protocol for the communication. It turned out that my general design was useless, since I did not anticipate all the aspect of the problem. But what did I learn from this rather embarrassing moment of my life as developer?

First of all I realized that I do not have the powers, like Nostradamus, to see into the future. I also came to the conclusion that you have to know the domain, before making any generalization. You have to do your first implementation in that domain, before you should make any general design. When you continue to evolve your product, you can figure out what parts of the code that is reasonable to generalize.

So I invented a rule that is "Premature generalization is the root of all evil design". It is of course inspired by "Premature optimization is the root of all evil". Nonetheless I think it is a good rule. This is why I choose to do a specialized tree structure for Microlog, instead of making a more general tree implementation. I have seen the phenomena of "premature generalization" in many projects since. For some reason it tends to be junior developers who fancies these general designs. Today many more people learns design patterns, than when I finished school. There is a big risk that you use to many design patterns, without really understanding the consequences. I prefer to get the code working and to deliver it in time for the demonstration. When adopting my golden rule stated above, this is not a problem. Thanks to agile methods, like Scrum, you are forced to make your application ready for demonstration early on. But that is another story.

6 comments:

Marcos Maia said...

Completely agree with you. That's one motive which refactoring and Unit Tests so important for a successful project.
2 really good books on these are Refactoring to patterns and the great Martin Fowler book Refactoring.
I've also learned the hard way(been there done that) and in my latest projects always focus on delivery first(The client don't give a sh.. about code anyway, do they??)!

[]s

My Open Source Software Development Blog said...

I have read the book "Refactoring to patterns" and I appreciated it really much. I put the other book on my already long reading list. Thanks for the tip!

Yapp, you said it right; delivery first!

Regards
Johan

Igor Maznitsa said...

I think it depends on the task and mainly on the preliminary data about the project, it is very often when we have only the title from a project as all data :)

My Open Source Software Development Blog said...

Of course there is no rule without exception. If you are in a situation where the goal is unclear you will be forced to have a general solution.

Regards
Johan

Offshore software development company said...

Thanks for sharing this article on Software development. It was very nice.

Looking for more..................Please continue.

Android App Development said...

Hello,great post. Information are pretty exciting and saved me huge amount of time which I have spend on something else instead of searching posts like this. I am waiting for more.