There’s a general misconception developers have, that you should always seek to write as little code as possible. This can sometimes lead to bad trade-offs, that make code worse. This case is a particularly good example of less code makes things worse.

I recently reviewed a class that basically looked like that:

    public class MyCoolClass
    {
        public IMyOtherStuff stuff;
        public EnumMyCoolClassType MyCoolClassType;
        public string Comment;
        public Exception Exception;
        public List<MyCoolClass> SubMyCoolClasss;

        public MyCoolClass(IMyOtherStuff stuff, EnumMyCoolClassType MyCoolClassType) 
            : this(stuff, MyCoolClassType, null, null, null)
        {
        }

        public MyCoolClass(IMyOtherStuff stuff, EnumMyCoolClassType MyCoolClassType, string Comment) 
            : this(stuff, MyCoolClassType, Comment, null, null)
        {
        }

        public MyCoolClass(IMyOtherStuff stuff, EnumMyCoolClassType MyCoolClassType, string Comment, Exception ex)
            : this(stuff, MyCoolClassType, Comment, ex, null)
        {
        }

        public MyCoolClass(IMyOtherStuff stuff, EnumMyCoolClassType MyCoolClassType, string Comment, List<MyCoolClass> subMyCoolClasss)
            : this(stuff, MyCoolClassType, Comment, null, subMyCoolClasss)
        {
        }

        public MyCoolClass(IMyOtherStuff stuff, EnumMyCoolClassType MyCoolClassType, string Comment, Exception exception, List<MyCoolClass> subMyCoolClasss)
        {
            stuff = stuff;
            MyCoolClassType = MyCoolClassType;
            Comment = Comment;
            Exception = exception;
            SubMyCoolClasss = subMyCoolClasss;
        }
    }

This class is basically a business entity, with 5 constructors. According to the guy who created this, this is good shit because it reduces code for the consumer (himself). Expect that I believe that this is an anti-pattern, that should be systematically replaced by the use of object initializers or by a single constructor using optional arguments.

Constructors are not for setting members. Setters are.

First, let’s emphasize that this is a business entity. It does nothing but store data. Adding a constructor kind of tells otherwise. Constructors are methods. As a consumer (and especially since I’ve been badly trained to integrate with bad code), my first reflex when I see that plethora of constructors will be to F12 them and find out what they do, cause I would suppose the constructor behaviour would change depending on which one you’re calling.

Adding constructors to business entities is usually the door by which you will enter to do things inside a BE that should not be there. Never forget that the world is full of careless people who will look for the shortest path to reducing their pain rapidly. And if you really need to do something in a business entity constructor, like validating data or something, you should really do it in the setter so that if data gets modified later, it will benefit from the same validation.

With object initializer on the other side, I know there is only a default constructor, and I’m just changing data. No stress.

Thou trade less code for more complexity

And it’s not even less code in the end

Second, I think that by doing specialized constructors like that, you actually trade code lines against added complexity, for several reasons:

1) It makes it harder to read on the consumer side, compare:

new MyCoolClass(this, EnumMyCoolClassType.Success, "Added stuff");

with

new MyCoolClass()
{
stuff = this,
MyCoolClassType = EnumMyCoolClassType.Success,
Comment = "Added stuff"
}

or with

new MyCoolClass(stuff: this, resultType: EnumMyCoolClassType.Success, comment: "Added stuff");

Yes, specialized constructor makes it slightly shorter (and we have auto-completion, + storage costs nothing), but then to know what each parameter correspond to, I effectively have to either run Intellisense, or to F12 it.

2) It increases the cost of adding a new field, if I want to add a field that I want to initialize at construction, then I’ll have to create new constructors, or change the constructors and touch everything that was referring them. This increases the risk of regressions, and the work.

3) It is contrary to the Interface seggregation principle, which means that I doubt it actually reduce the amount of code you write: let’s face it, the constructor you have available never really correspond to your need, there are always fields you would not want to initialize, or you miss the combination corresponding to your need. Unless you have the combination of all the fields you need, you’re doomed to write new constructors.

Instead of that, object initializers bring, yes, a bit more code for consumers, but less risk, more clarity, more maintainability, at very little cost. So why not using them?

If you need more than one constructor you might need more than one class

or not a constructor

Finally, you will probably tell me that in the case of a worker class (everything that is not a B.E.), what I’m telling you is stupid, and that I’m stupid altogether. It’s not. And I might be.

What are the common reasons behind having several constructors for a worker class:

  • Setting different members that are not used in the constructing logic in which case I dealt with that above;
  • Have different dependency initialization, such as initializing from a file or from content directly, or using a file or database, in which case you most probably miss a dependency invertion somewhere for the sake of simplification, at the cost of delayed pain;
  • Have different constructing logic, such as loading an entity from its ID in one case, loading it from its name in the other, or creating a new one in the end. In any of these cases you should probably consider using a factory instead. Consider:
var yeahhh = new MyCoolClassThatIsNotAnEntity(this.CoolObject.SomeReferenceId);

versus

var yeahhh = MyCoolClassThatIsNotAnEntity.LoadFromId(this.CoolObject.SomeReferenceId);

Soooo

Yeahhh for unique constructors that do one thing. BOooh for others!