Definitive Behavior

A constructor is often said to initialize an object. But in my experience I have found that constructors are much more than that. They are the first method to be called in an object's lifetime, and you can call only one. So these special methods have earned more respect than to be treated as mere initializers.

The word "initializer" implies that the method sets the initial value of member variables. It is assumed that these variables can change their values at any time. But if a constructor is an initializer, then it is merely a convenience. There is no difference, say, between these two pieces of code:

Person person = new Person("Michael", "Perry);

or

Person person = new Person();
person.FirstName = "Michael";
person.LastName = "Perry";

If there are two ways of expressing the same idea, then the object's interface is bloated (see Necessary and Sufficient). The constructor should only set a value only if it can be set in no other way. It's parameters should be those things that do not change over the course of an object's lifetime.

I have found that objects have three types of behavior. The kind that we are most familiar with is dynamic behavior: things that can be changed. A member variable represents dynamic behavior because I can change its value (and therefore the behavior of the object) at any time. The FirstName and LastName properties of the Person class in the above example are dynamic.

The second kind is dependent behavior: things that depend upon other things. Dependent behavior is usually manifested as read-only member functions. They don't change the object; they calculate some value based on the state that the object already has. We might add a read-only FullName property to the Person class that concatenates the first and last names.

The third kind is definitive behavior: things that don't change during an object's lifetime. An object is constructed with this behavior, and it will keep it until it is destroyed. These behaviors are represented as constructor parameters, and often as read-only properties ("getters"). If they are values, they are usually identifying attributes, such as database keys or IDs. But quite often they are references to objects of larger scope, such as a business object for a UI component, or a storage provider for a message queue.

The best practice I've found is to avoid overloaded constructors. Reserve the one and only constructor for definitive behavior. This clearly documents to the users of the class that you have only one chance to set these values. You can only call one constructor. Use it wisely.

Leave a Reply

You must be logged in to post a comment.