How do you construct your objects?
I love it when an object is designed in a way that allows me to use it without forcing me to ask or wonder how it should be initialized. Good enough? Ok, let’s go further…
Let’s start with a simple example of a Person class. One way I could write the class is like this:
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
// No constructors defined means the compiler will create a default (parameterless) constructor for us.
}
All right, so if I want to use this class, I need to know or figure out which properties of my newly instantiated Person object to set before actually using it. This is an important step, because if the object participates in some method that requests a valid value from one of its properties, and that property isn’t in a valid, coherent state, then we might not get the expected result and debugging the problem might be cumbersome. In our case, since a Person object is fairly straightforward and common, we pretty much know that its FirstName and LastName properties should be set prior to use it. But what about its Age? Let’s suppose that the Age is as important as the FirstName and the LastName. Let’s also suppose that there are a bunch of other properties that defines a Person, such as Weight, Height, EyesColor, HairColor, Cavities, Faith, etc. How can we possibly know that we must set the Age property when IntelliSense gives us a myriad of other properties belonging to this object? Frankly, we can’t, unless the author of the class tells us or it’s documented somewhere (but then again who documents code, right?).
I believe that if the author of the Person class had use an intention-revealing technique to design the class, such as Test-Driven Development, she probably would’ve thought about how to properly initialize the class. But then again, even that depends on the developer’s experience, philosophy and imagination on designing object-oriented software.
When designing objects, it’s important to ask ourselves a few questions prior to coding. For example, should we provide a parameterless constructor (which will force the clients of the object to properly initialize its members)? Should we provide constructors which accept parameters to properly initialize the object so that it’s ready to be used? Even that question forces us to ask whether or not we should fully or partially initialize the object.
Whenever I instantiate an object, I like to know the information it needs to be properly initialized (ReSharper is pretty helpful in such a scenario). In other words, I want to know the “what” NOW…not later. Furthermore, I don’t want the clients using my object to think too much about these concerns either. I just want them to instantiate the object and be ready to start using it. Am I asking for too much here? I don’t consider myself a good programmer if I remove the developer out of the “zone” whenever she uses my objects. It’s like constantly turning on and off a lighting switch…it gets annoying…very annoying. That being said, if I take our previous little example, I would design the Person class as the following:
class Person
{
public Person (string firstName, string lastName, int age)
{
// Implementation…
}
// No more constructors…not even a default (parameterless) constructor.
}
This constructor implementation would be valid if I want this object to be initialized with a FirstName, LastName and Age upon instantiation. How can I know whether or not this is a “good” practice? In most cases, you can probably find the answer directly in the requirements document, but again I strongly believe that it depends on one’s own experience, philosophy and imagination with object-oriented design and programming. Nevertheless, with the now refactored Person class, I can easily communicate to the client of that class what she needs to provide to the object for it to be properly instantiated and ready to use. I don’t make her think…I don’t push her out of the “zone”.
Another way to think about it is that when you go to the bank to open a new account, the bank teller doesn’t just hand you over a new “empty” account. First, she asks you a few questions and gets some information from you, such as your name, your address, your credit history, etc. Does it make sense for her to ask those things? Absolutely, because it makes sense in the process of creating a bank account. Going back to our Person class, does it make sense for that object to ask you to provide a FirstName, LastName and Age information prior to creating one? Well, it also depends on the process of creating a Person object in your business domain. (Software development is a field where there’s a lot of those “well, it depends!” moments).
Let me wrap up this idea by giving you two more examples from the .NET Framework. If you search for the “MailMessage” class with Reflector, you will see that there are two MailMessage classes in the search results (see the picture below). One of these belongs to the System.Net.Mail namespace and another one belongs to the System.Web.Mail namespace. They both provide the same functionality, but the one from System.Web.Mail is actually obsolete. In fact, it’ll ask you to use the one from the System.Net.Mail namespace instead.
Figure 1. Search results for “Mail Message” in Reflector

If we look at MailMessage from System.Net.Mail, we’ll see the following four constructors:
- A public parameterless constructor which initializes an empty instance of it.
- Another public constructor which accepts two MailAddress objects as parameters (one is the source MailAddress and another the destination MailAddress)
- Another public constructor which accepts two string parameters (the source email address and the destination email address)
- Another public constructor which accepts four string parameters (the source email address, the destination email address, the subject and the message body)
I can understand that providing multiple ways to instantiate such an object is required in this context, because this MailMessage object belongs to a framework and not a custom application. As Kent Beck righteously points out in his latest book, “Implementation Patterns”, there is a big difference in the way objects are designed and built in a framework versus a custom application. As you can see, these constructors are telling me what specific information I should provide them in order to instantiate a fully working object.
Now take a look at the obsolete MailMessage class from System.Web.Mail. You might expect the same number of constructors as the one from System.Net.Mail. Instead, this one only provides one constructor: the default parameterless one. Oh boy! Now, the client of this class must know which properties (Attachments, Bcc, Body, BodyEncoding, From, CC, etc.) to set before actually using the object. She is getting out of her “zone”…the light bulb is flashing…it’s annoying. Good thing this one is now obsolete.
I still see much code in custom application that doesn’t offer the developer the guidance to properly instantiate an object prior to using it. This forces us to ask ourselves “Ok, now that I have instantiated this object, what exactly do I need to provide it with for it to work properly?”. I hate asking myself these questions. I just want to use the object. I want to think about more important things that knowing which properties to set. If you’re at this crossroad and need to know what kind of information should an object request in its constructor, writing a unit test for it prior to coding might reveal a powerful weapon to counter the never-ending battle in our minds when designing good objects.
What other tricks or ways do you know about writing good object constructors?
Similar posts you might be interested in reading:
- Avoid calling a virtual or abstract method from a constructor in C#…especially in VB!
- Evolving your design with the Principle of Least Knowledge
- Explicit Interface Members Implementation in C#
- Would Your Objects Praise You?
- Better Modelling with the Visual Studio Class Designer
- Getting Familiar With Your Basic .NET Delegates
- String vs StringBuilder for the .NET Concatenation Performance Championship






Arjan`s World » LINKBLOG for September 10, 2008:
[...] How do you construct your objects? – Brian di Croce ‘ As Kent Beck righteously points out in his latest book, “Implementation Patterns”, there is a big difference in the way objects are designed and built in a framework versus a custom application ‘ [...]
September 11, 2008, 3:04 amReflective Perspective - Chris Alcock » The Morning Brew #178:
[...] How do you construct your objects? – Brian Di Croce looks at object construction and suggests that its a good idea to really think about your constructor, and ensure that they leave the constructed object in a good state to use. [...]
[WORDPRESS HASHCASH] The comment’s server IP (212.227.118.27) doesn’t match the comment’s URL host IP (82.165.100.165) and so is spam.
September 12, 2008, 2:48 amPaul Raubertas:
Very good article! I’ve always wondered about this topic myself having been exposed to various different ways in which other developers create their classes. I don’t if in the end there is one true, absolutely iron clad way to develop objects and certainly requirements more often then not play a big part. For my part it’s really a combination of good OO practices and requirements. My “typical” business classes often take this form (and this is really from the school of thought I was brought up on as a “developer in grooming”
:
class Person() {
#region ” Members”
public int mOID;
public string mFirstName;
public string mLastName;
public int mAge;
#endregion
#region ” Properties”
public readonly int OID() { get; }
public string FirstName() { get; set; }
public string LastName() { get; set; }
public int Age() { get; set; }
etc….
#endregion
#region ” Constructors”
public Person() {
// default constructor
}
public Person(int id) {
mOID = id;
… Method to load an instance from an existing id.
}
public Person (string fn, string ln) {
mFirstName = fn;
mLastName = ln;
…. Method to load an instance from existing first and last name.
}
}
}
September 18, 2008, 2:11 pm