Home > Various > Bring on the default constructors

Bring on the default constructors

The term “default constructor” refers to a constructor that is automatically generated in the absence of explicit constructors (and perhaps under other circumstances); this automatically provide constructor is usually a nullary constructor. In specification or discussion of some languages, “default constructor” may additionally refer to any constructor that may be called without arguments, either because it is a nullary constructor or because all of its parameters have default values.
Wikipedia

Abstract

In which the author outlines why default constructors on domain objects are not a ‘code smell’ for NHibernate and are actually required in most situations.

Concrete

I remember when I first started working with (N)Hibernate. It seemed like  a great tool: no more writing SQL queries, no more writing mapping code, but there was that expletive requirement to have a default no-arguments constructor. So I made that private as to not allow the constructor to be abused, but it still seemed bad: the domain object needs to conform to what an infrastructure framework wants.  It is only now, years after my first encounter with NHibernate, that I see that having a default constructor is not a bad thing. If anything, default constructors on domain objects are good things.

Let’s look at the reason why we need constructors. The raison d’être for a constructor is to force code that news up an instance of a class to provide other objects that said class needs.  In the context of domain layer and domain objects we tend to think of this as ‘creating the object in a state that is valid’. But what is a valid state?  When talking with programmers, analysts or domain experts it’s very easy to define what is a valid state.  In a classical order system with customers valid state will probably include a customer having a first name, last name and valid address details.  But is this really such a big requirement that we have to validate this in the constructor?

Weather or not a domain object is valid is in some cases not up to the object itself, and this is especially true for new instances.  Fact of the matter is that the only thing that determines if a domain object is valid is context.  Why does a customer need a first name, last name and an address? Because we need to be able to ship orders to him.

Read that again. We need to ship orders to him. If we are not shipping orders we do not need to validate anything. This brings the concept of validation into a totally different area. We no longer need to think about validating domain objects after creation, we are now validating pre-conditions for object creation.  This validation is always external to the object being created, allowing you to use the same domain object for different use-cases, without the need to write, test and maintain a gazillion different constructors, or even worse – deal with constructors that have the same parameters but different validation requirements. (The question of where the actual validation occurs for certain domain objects – such as aggregate roots – is a matter I’l talk about in a different post.)

Conclusion

And that, ladies and gentlemen, is why I like default constructors. Because I really don’t care if my domain objects are valid or not. All I care about is that they are valid in the context I’m using them in. And validating that can be done with re-useable code, tried and tested through unittests and talks with domain experts. Full of DDD and OO goodness, just the way I like it.

Categories: Various Tags:
  1. No comments yet.
  1. No trackbacks yet.