Avoid Premature Generalization

You’ve no doubt heard me rant against premature optimization in the past, but Eric Gunnerson points out another “Premature” action to be avoided, “Premature Generalization”.

His discussion centers around a very specific question of whether to use private properties to access private fields, or just allow access to the field. Note this discussion pertains to fields that are not publicly accessible via property nor direct access.

The place you’ll often see premature generalization is when inexperienced developers start applying Design Patterns everywhere. If you need to instantiate a factory, implement an adapter class and use a bridge to the toilet just to take a dump, then you probably live with a developer with a premature generalization problem.

Like optimization, generalization is good when it is applied judiciously in the right places. With optimization, one should measure measure measure before applying optimizations. With generalization, I typically suggest that a developer must feel the pain first before generalizing. That simply means that the lack of generalization is starting to cause more work than it saves. In my experience, this often boils down to the rule of threes. If you have to implement something a third time, refactor it.

For example, suppose you have an import tool for some system and as far as you know, you’ll only have to support one import client. By all means write an importer specific to that client. Now your boss tells you to implement an importer for another client. Write that one specific to that client. Once again your boss tells you to implement an importer for yet another client. At this point a pattern has been established. Your boss is a liar and you’ll probably need to implement importers for many clients. Now is the time to refactor the code and generalize the concept of importers. Maybe create a plug-in model or an Import Provider.

[Listening to: Cass & Slide / Perception - Sasha - Sasha: Global Underground: Ibiza [2 of 2] (9:27)]

What others have said

Requesting Gravatar... Sharp as a Marble Sep 19, 2005 12:56 PM
# re: Avoid Premature Generalization
I've been known to have a problem with premature commenti....
Requesting Gravatar... Ryan Farley Sep 19, 2005 1:05 PM
# re: Avoid Premature Generalization
Yes, I've been known to suffer from premature generalization from time to time.

http://ryanfarley.com/blog/archive/2004/04/30/570.aspx

Not a problem I am proud of, but a strugle I deal with every day... ;-)
Requesting Gravatar... you've been HAACKED Sep 19, 2006 9:41 AM
# re: A Few Questions For Subtext Users
re: A Few Questions For Subtext Users
Requesting Gravatar... you've been HAACKED Jun 12, 2007 12:05 AM
# Introducing Subkismet-The Cure For Comment Spam
Introducing Subkismet-The Cure For Comment Spam
Requesting Gravatar... Mike Seth Aug 25, 2008 2:21 AM
# re: Avoid Premature Generalization
To my experience, the kind of generalization you speak of works best in certain junction points of your software. For example, a factory pattern works well when applied to major replaceable components, but it's completely redundant to spawn instances of every class using a factory. In general, design patterns can't replace foresight, and foresight is achieved from experience.
Requesting Gravatar... Sijin Joseph Aug 25, 2008 5:08 AM
# re: Avoid Premature Generalization
I had written about a similar experience a while back, check it out at www.indiangeek.net/.../do-not-start-with-an-int...
Requesting Gravatar... Felipe Aug 25, 2008 6:09 AM
# re: Avoid Premature Generalization
Great example!

Premature * is evil.
Requesting Gravatar... Eric Aug 25, 2008 8:13 AM
# re: Premature * is evil.
Yes, premature implies that it's done too early. It wouldn't be too early if it didn't matter that it was done early.
Requesting Gravatar... Joel Aug 26, 2008 12:09 PM
# re: Avoid Premature Generalization
The author rightly says a developer must feel the pain first before generalizing. But foreseeing the pain and not generalizing is just being plain lazy. copy-pasting of code, only make the developers life more difficult.
From my experience, avoiding generalization always and diving straight into the problem hoping you would do it only if required sometimes costs more (time) than if you had designed and generalized the problem to begin with.
Requesting Gravatar... matt Oct 24, 2008 3:16 AM
# re: Avoid Premature Generalization
I would disagree with three instances of something. Two is enough pain for me to want to generalize, and a valid place to generalize from.

Obviously, the generalization I would use for two would probably just be an interface, but that would be enough to begin with. Wouldn't want to be too premature!
Requesting Gravatar... Dan M. Apr 24, 2009 10:13 PM
# re: Avoid Premature Generalization
I recently upgraded to the latest version of Visual Studio, and I've started looking into some of the newer C# features. One that really has me struggling is this "Automatically Implemented Properties" business that was introduced with C# 3.0. Before I knew about these (or at least before I was willing to think about trying to use them) my default policy was to declare private fields and expose them on an as-needed basis with public (or protected) properties. This has generally worked well for my purposes, but now, with these super-easy-to-declare properties with no (visible) backing field, I feel lost. If you use an automatic property, you don't even have the option to refer to the backing field. So, now, if you stick to only
Requesting Gravatar... Dan M. Apr 24, 2009 11:01 PM
# re: Avoid Premature Generalization
I came across your blog because I've been trying to figure out what the "best practice" is regarding private properties. I honestly never gave this much thought until I started to look into using some "automatically implemented properties". It has really opened up a huge can or worms for me. My natural tendency had always been to do just as you say--only use properties when there is an actual need for the underlying data to be accessed outside the class. But now, with this newfangled way of declaring properties, I suddenly have all these questions: Do I want to use automatic properties at all? If I do, do I want to go to the opposite extreme and use them whenever possible? And if I do this, does it mean I should never refer to fields directly since, often, I wouldn't even have the option to do so? One strategy that comes to mind would be to use automatic properties only in situations where I would have used "manual properties"--because I need to allow access outside of the immediate class. This means that, even privately, I would use the property (no choice in the matter). Fine so far, but what do I do with readonly fields and fields that require initialization? You can't automatically implement properties for those--you have to write up the properties the old fashioned way. In those cases, when I "get" the data privately, should I continue to refer to the private backing field or should I switch over to using the property? And of course this begs the question, even if I choose never to use automatic properties, should I still get into the habit of referring to data via its property (rather than its field) the moment I decide to use a property? I would love to hear your take on this (and definitely point me to any entry you've already written on the subject).
Requesting Gravatar... haacked May 04, 2009 9:15 AM
# re: Avoid Premature Generalization
@Dan, you can use automatic properties for readonly. For example:

public string Foo {
  get;
  private set;
}
I generally like using automatic properties for simple properties.

What do you have to say?

(will show your gravatar)
Please add 3 and 6 and type the answer here: