Skip to content

Favour Non-Default Constructors Over Default Constructors

June 8, 2009

This is basically a rehash of my earlier post, where I asked whether my objects should have a default constructor, and we (or, at least, I) came to the conclusion that default constructors are evil. I keep finding myself referring back to the fact that default constructors are evil, and thought it might help to have a more concise summary of why you should favour non-default constructors over default constructors.

So, should objects have a default constructor, and if so, what should it do? The short answer is; default constructors are evil. Don’t write them (and don’t let the compiler write one for you). Don’t use them, unless it really makes sense to do so.

How do you tell if it makes sense to do so? Consider the following:

  • Does your object have a natural “null” or default state, applicable in all cases? If not, then you don’t want a default constructor, because you can’t have it Do The Right Thing™.
  • Would a static (special value) better convey your intent? Having to explicitly use Double.NaN is better than having a Double object that default-constructs to NaN.
  • Construction implies that an object is ready-for-use; if a default-constructed object isn’t ready-for-use, then you shouldn’t have a default constructor.

I’ll agree that what I’ve written there is slightly repetitious, but it’s worth trying to hammer the point home. What I’ve come to find is that default constructors are a type of “secondary code smell” – they stink, and there’s usually a bigger stink going on that also needs addressing.

Which is the whole point of me posting this; so that when it comes up as a symptom of other problems, I can point to this article and remind you that…

default constructors are evil.

Advertisements
3 Comments leave one →
  1. June 8, 2009 10:50 pm

    I like moving all configuration out of objects and passing in the dependencies.

    However, at some point in your system you’re going to need a default constructor. Whether that’s at the top level, or for each subsystem, they’re going to need to configure themselves.

    I often test classes by passing mock objects into non-default package visible constructors. But the public constructor is default and creates the default configuration for the subsystem.

    Where the configuration meets an external system I try to encapsulate that. Reading files, environment variables, system properties, database, etc, is encapsulated and replaceable for testing. After all, unit tests shouldn’t talk to the file system or database.

    I wonder whether the lower objects are in the system, the less likely they are to be able to configure themselves correctly. Or maybe only system entry level classes are likely to know how to default construct themselves.

  2. June 9, 2009 9:35 am

    Hi Pete,

    Yes, I think that there’ s another issue here, about how you join together all these non-default-constructed objects; which is why I’ve gone for the “favour non-default over default” guideline (and then probably devalued my message by sensationalising it with “default constructors are evil“) .

    Unfortunately (as always) I’m at least three posts behind your thinking. I’d planned to address the joining-up of dependency-injected classes in a later post, and I’ll do my best to add your idea of non-default package visible constructors to the debate (though you might want to chip in when the time comes ;-).

    Rereading what I’ve written here I’ve probably been a little too absolute. You’re right; I’m talking about lower objects in the system, but the majority of what we write should be lower-level objects with a single responsibility to do one thing and do it right.

    Hopefully once I’ve written up my examples for when and why default constructors are evil, it will give the reader a better picture of what I’m trying to get at.

Trackbacks

  1. Favour Constructors Over Setters - dantwining.com

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: