One of the blogs I subscribe to is by Reginald Braithwaite. He was recently interviewed on InfoQ and part of the conversation related to the development process of generalizing in programming:
……so again I apologize for digressing, but I found this to be an important point in my own programming, and I don’t know if that’s a general point but quite often we see something and we are very tempted to say “Oh, this is a special case of a more general thing”, and then we solve the general thing. However that is an infinite recursion, it’s always the special case of something more general. And if you are always climbing up the tree into the more general thing you will eventually wind up with a PhD in computer science and no code.
However on the other hand, if we just scrabble around the Earth, and we never sort of poke our head around to see the more general thing. We are constantly resolving the same problems, we are not even recognizing that two different things we solved are both aspects of the same thing. So what I try to do is I always try to recognize what the general case is and then discipline myself not to solve the general case until it’s really an imperative, but not to be ignorant of the general case. So coming back to your question, at the moment I am aware that it is a general case, and I am fighting on an almost daily basis not to make it too general
This is such a fundamental decision that comes up time and time again in software development. I think Reginald is spot on in his approach of not going down the generalization rabbit hole every time, but never forgetting that there’s an incredible amount of waste associated with always working on just the specialized case. Sentiments such as YAGNI are great guiding principles but can be damaging if they preclude doing any generalization work at all.