Constructors vs Factory Methods

ooadoop

When modelling classes, what is the preferred way of initializing:

  1. Constructors, or
  2. Factory Methods

And what would be the considerations for using either of them?

In certain situations, I prefer having a factory method which returns null if the object cannot be constructed. This makes the code neat. I can simply check if the returned value is not null before taking alternative action, in contrast with throwing an exception from the constructor. (I personally don't like exceptions)

Say, I have a constructor on a class which expects an id value. The constructor uses this value to populate the class from the database. In the case where a record with the specified id does not exist, the constructor throws a RecordNotFoundException. In this case I will have to enclose the construction of all such classes within a try..catch block.

In contrast to this I can have a static factory method on those classes which will return null if the record is not found.

Which approach is better in this case, constructor or factory method?

Best Solution

Ask yourself what they are and why do we have them. They both are there to create instance of an object.

ElementarySchool school = new ElementarySchool();
ElementarySchool school = SchoolFactory.Construct(); // new ElementarySchool() inside

No difference so far. Now imagine that we have various school types and we want to switch from using ElementarySchool to HighSchool (which is derived from an ElementarySchool or implements the same interface ISchool as the ElementarySchool). The code change would be:

HighSchool school = new HighSchool();
HighSchool school = SchoolFactory.Construct(); // new HighSchool() inside

In case of an interface we would have:

ISchool school = new HighSchool();
ISchool school = SchoolFactory.Construct(); // new HighSchool() inside

Now if you have this code in multiple places you can see that using factory method might be pretty cheap because once you change the factory method you are done (if we use the second example with interfaces).

And this is the main difference and advantage. When you start dealing with a complex class hierarchies and you want to dynamically create an instance of a class from such a hierarchy you get the following code. Factory methods might then take a parameter that tells the method what concrete instance to instantiate. Let's say you have a MyStudent class and you need to instantiate corresponding ISchool object so that your student is a member of that school.

ISchool school = SchoolFactory.ConstructForStudent(myStudent);

Now you have one place in your app that contains business logic that determines what ISchool object to instantiate for different IStudent objects.

So - for simple classes (value objects, etc.) constructor is just fine (you don't want to overengineer your application) but for complex class hierarchies factory method is a preferred way.

This way you follow the first design principle from the gang of four book "Program to an interface, not an implementation".

Related Question