Pergunta

According to following article Named Constructors The Author suggests using static factory pattern to construct objects is way better than instantinate with new keyword. At the begining the idea is appealing(according to some details in article) yes method names are more obvious and it gives a sense that the construction of the class it is not dependent to it's contstructor but class has different behaviours according to different problems on construction level.

<?php
$customer = new Customer($name); 
// We can't "new a customer" or "instantiate a customer" in real life.
// Better:
$customer = Customer::fromRegistration($name);
$customer = Customer::fromImport($name);

But the problem I see here according to this idiom we are using class methods like functions! And according to the above example it creates coupling issues we have to wrap this static factories with an injectible factory to decouple from the rest of the application?

Could you please clarify me to understand this. I started to see this idiom all around in PHP community and even in some Java examples.

Foi útil?

Solução

Named Constructors in PHP

Don't limit yourself by PHP's single constructor. Use static factory methods.

The article is not about coupling. There is zero difference in coupling between using new Customer(/* some args */) and Customer::fromFoo(/* some args */). Where you put those expressions determines how coupled they are. All the "Factory Pattern" boils down to is "expression returning object".

The difference is instead about working around PHP's restriction on a class having a single constructor. If you want to have multiple ways of constructing a class, there are two choices:

  • distinguish them in the single constructor, from the arguments
  • distinguish them with multiple static factories, which take different arguments from each other.

Outras dicas

In PHP we don't have multiple constructors per class but that won't help anyway because they would be named the same: __construct, a term that is not from the ubiquitous language.

But why do we use a constructor anyway? We use it to correctly initiate an object to a valid initial state. We can do that by making the properties private, which also helps in protecting the object encapsulation. This means that they can be changed only from the context of the class. The problem is that there could be more than one valid initial state for many of our objects. So, in order to allow only initial valid states and to protect encapsulation we can use class static methods as object constructors, one for each use case.

In C++ there are friend classes that may access private properties and so they can have a friend class as factory for each use case but we don't so we must use static methods.

BTW, using static methods doesn't break encapsulation because the context is class. You can see that by the fact that PHP let you access private properties and methods also from static class methods.

Licenciado em: CC-BY-SA com atribuição
scroll top