oop when Constructors vs Factory Methods




when to use static factory method (8)

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?


Sometimes you have to check/calculate some values/conditions while creating an object. And if it can throw an Exception - constructro is very bad way. So you need to do something like this:

var value = new Instance(1, 2).init()
public function init() {
    try {
        doSome()
    }
    catch (e) {
        soAnotherSome()
    }
}

Where all additional calculations are in init(). But only you as developer realy know about this init(). And of course, after months you just forget about it. But if you have a factory - just do all you need in one method with hiding this init() from direct call - so no problems. With this approach is no problems with falling on creation and memory leaking.

Someone told you about caching. It's good. But you also have to remember about Flyweight pattern which is nice to use with Factory way.


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.

This process should definitely be outside a constructor.

  1. Constructor should not access database.

  2. The task and the reason for a constructor is to initialize data members and to establish class invariant using values passed into constructor.

  3. For everything else a better approach is to use static factory method or in more complex cases a separate factory or builder class.

Some constructor guide lines from Microsoft:

Do minimal work in the constructor. Constructors should not do much work other than to capture the constructor parameters. The cost of any other processing should be delayed until required.

And

Consider using a static factory method instead of a constructor if the semantics of the desired operation do not map directly to the construction of a new instance.


A concrete example from a CAD/CAM application.

A cutting path would be made by using a constructor. It is a series of lines and arcs defining a path to cut. While the series of lines and arcs can be different and have different coordinates it easily handled by passing a list into a constructor.

A shape would be would be made by using a factory. Because while there is a shape class each shape would be setup differently depending on what type of shape it is. We don't know what shape we are going to be initializing until the user makes a selection.


Use a factory only when you need extra control with object creation, in a way that couldn't be done with constructors.

Factories have the possibility of caching for example.

Another way to use factories is in a scenario where you do not know the type you want to construct. Often you see this type of usage in plugin factory scenarios, where each plugin must derive from a baseclass or implement some kind of interface. The factory creates instances of classes that derive from the baseclass or that implement the interface.


By default, constructors should be preferred, because they are simpler to understand and write. However, if you specifically need to decouple the construction niceties of an object from its semantic meaning as understood by the client code, you'd be better off using factories.

The difference between constructors and factories is analogous to, say, a variable and a pointer to a variable. There's another level of indirection, which is a disadvantage; but there's another level of flexibility too, which is an advantage. So while making a choice, you'd be well advised to do this cost versus benefit analysis.



A cite from "Effective Java", 2nd ed., Item 1: Consider static factory methods instead of constructors, p. 5:

"Note that a static factory method is not the same as the Factory Method pattern from Design Patterns [Gamma95, p. 107]. The static factory method described in this item has no direct equivalent in Design Patterns."


In addition to "effective java" (as mentioned in another answer), "clean code" also states that: prefer static factory methods (with names that describe the arguments) instead of overloaded constructors. Eg, don't write

Complex complex = new Complex(23.0);

but instead write

Complex complex = Complex.fromRealNumber(23.0);

The book goes as far as to suggest making the Complex(float) constructor private, to force the user to call the static factory method.





ooad