Using service factory over service configurator is better decision in a few special cases:
1) Creating service definitions for older PHP classes since, in the past, creation logic was often hidden inside static factory classes
For example, Doctrine_Core::getTable()
public static function getTable($componentName)
{
return Doctrine_Manager::getInstance()->getConnectionForComponent($componentName)->getTable($componentName);
}
https://github.com/doctrine/doctrine1/blob/master/lib/Doctrine/Core.php
2) One particularly nice example of using a factory service and method for retrieving a service is the
case of a Doctrine repository. When you need one, you would normally inject an entity manager as
a constructor argument and later retrieve a specific repository:
use Doctrine\ORM\EntityManager;
class SomeClass
{
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
public function doSomething()
{
$repository = $this->entityManager->getRepository('User');
}
}
But using a factory service and method you could directly inject the correct repository itself:
class SomeClass
{
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
}
...
<service id="some_service" class="SomeClass">
<argument type="user_repository" />
</service>
...
<service id="user_repository" class="UserRepository"
factory-service="entity_manager" factory-method="getRepository">
<argument>User</argument>
</service>
By looking at the constructor arguments of SomeClass it is immediately clear that it needs a
User repository, which is much more specific and communicative than the earlier example in which
SomeClass needed an EntityManager . Besides making the class itself much cleaner, it will also make
it much easier to create a stand-in object for the repository when you are writing a unit test for this
class. Instead of creating a mock for both the entity manager and the repository, you only have to
create one for the repository itself.
Drawbacks of using service factory are (according to Matthias):
My objection to factory classes with static factory methods is that
static code is global code and that executing that code may have side
effects that can not be isolated (for instance in a test scenario).
Besides, any dependency of such a static factory method has to be by
definition static itself, which is also really bad for isolation and
prevents you from replacing (part of) the creation logic by your own
code. Factory objects (or factory services) are slightly better.
However, the need for them very likely points to some kind of design
problem. A service should not need a factory, since it will be created
only once in a predetermined (and deterministic) way and from then on
be perfectly reusable by any other object. The only things that are
dynamic about a service, should be the arguments of the methods that
are part of its public interface