Static factory pattern vs. Named constructor idiom vs Named constructor. Wait, what…?

Posted: November 25, 2016 in Programming
Tags: , ,

There are several ways to construct object instance. Most common way is to use, of course, a ‘new’ keyword, however, as anything else, both theory and practice have decide to make this more complicated, and invent new fancy terms for it.

GoF (https://en.wikipedia.org/wiki/Design_Patterns) are not authors of “static factory pattern”, however, it is one of the most famous and simple construction pattern in any object-oriented programming language and it is fairly used in PHP.

Definition of the constructor

Constructor is special method of the class that can be invoked by using either a “new” keyword (new Object()) in the process of object instantiation, or by using reflective voodoo, which depends on support of programming language that is being used (however, reflections are, usually, an edge case and irrelevant and out of the scope of this article).

Constructor can produce ONLY two results of its invocation:

  • A pointer to a new instance of the class that is being constructed
  • An exception

Practical problems with process of object construction

There are certain problems that may occur when it comes to constructing object when we use class constructor.

1. Constructor do not expose its intent

We know that constructor will construct the object, but we can not know how its going to do that. In majority of scenarios, that is not an issue, however, in certain use cases, that can be somewhat important, consider this example:

class Person
{

}

class Client
{
    const REGULAR = 'regular';
    const VIP = 'vip';

    private $person;
    private $type;

    public function __construct(Person $person)
    {
        $this->type = self::REGULAR;
        $this->person = $person;
    }
}

Pay attention to Client class and its constructor. From implementation details we know that it will construct a “regular” client, however, if we do not inspect it, we can not know that (except if we are provided with proper documentation).

By using a static factory pattern, we can explain intent of object construction process:


class Client
{
    const REGULAR = 'regular';
    const VIP = 'vip';

    private $person;
    private $type;

    private function __construct(Person $person, $type)
    {
        $this->type = $type;
        $this->person = $person;
    }

    public static function createVipClient(Person $person)
    {
        return new static($person, self::VIP);
    }

    public static function createRegularClient(Person $person)
    {
        return new static($person, self::REGULAR);
    }
}

2. Constructor will always create a new instance of class. 

Well, that is its purpose, right?

It is, but sometimes you need to have only one instance of some class (https://en.wikipedia.org/wiki/Singleton_pattern), or you want to have several, named instances (https://en.wikipedia.org/wiki/Multiton_pattern), or it is just too expensive to construct a new instance so you will try to reuse already created, unused instances first (https://en.wikipedia.org/wiki/Object_pool_pattern), etc…

You have to prevent uncontrolled object instantiation, so constructor would have to have a “private” as access modifier. So only reasonable implementation method of constructor would be a static factory pattern (you can use reflections as well, but that is arguable in this case).

3. Constructor will always create a new instance of its class

Again, that is its purpose, right?

However, in some languages, like Java, it is possible to have a private class, or visible only within the scope of the package (library). By implementing static factory pattern, it is possible to create and return instance of any other class.

Per example, in some scenarios, which implementation should be used can be determined in runtime only, where it is required to inspect execution environment, or, based on provided parameters a certain class instance would be constructed and provided. Of course, all possible instances that can be provided by implementation of static factory pattern should implement some predetermined interface, so all of this could have sense.

This possibility is very useful in languages that have feature of private classes or visible within package/library scope.

When it comes to PHP, usefulness of this possibility is very limited and it is constrained to anonymous classes.

4. Some languages don’t support constructors/methods overloading in traditional sense

Languages like PHP do not have possibility to overload constructors/methods, like Java, C#, etc… Something similar can be achieved with “func_get_args()“, however, that approach is arguable, therefore it is deliberately stated that “PHP does not support constructors/methods overloading in traditional sense“.

Implementing static factory pattern can provide us with solution for constructors overloading, that is, multiple constructors.

A side note: In talk which I held on November 15th, Y2016 organized by PHP Serbia, I have stated that overcoming a lack of language support is not a design pattern (https://www.slideshare.net/secret/6dZyaQKrYwPGkj, slide 42., footnote). However, I have to admit that I have doubts about this particular use case, on which I have not found (yet) a points of view by “higher minds”. So for now, I will admit that that statement is arguable and it is quite possible that I was wrong.

The origins

I couldn’t find the origin of “Static factory pattern“, nor the name of the author of the pattern. Neither I could find author of “Named constructor idiom” as well. However, I am pretty sure that C++ is inventor, and concept is stolen by Java from C++, renamed for marketing purposes in the “very beginning of the time” – while rest joined the party afterwards, and used the term with word “pattern” in it – because it is more cool, patterns are cool.

Of course, PHP community decided not to use neither of original names, but to mutilate one of those. And that is how we have a “Named constructor” term – as if there is no enough names for same thing.

How to call it, then?

Named constructor” is wrong name for sure, it is not a constructor because it violates the very definition of constructor – constructor can return only a instance of its class or throw an exception. There is no third option – whatever you do, you can get only those two results. Static methods on the other hand can produce every imaginable result, so this name is not suitable for sure.

However, “Named constructor idiom” is quite suitable, word “idiom” do make difference.

Personally, I prefer “Static factory pattern“, it explains intent, gives a hint how to implement it, and by having “pattern” in name explains that it is a recipe for solving some common development problems.

 

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s