15

Magento 2 is using factory classes for non-injectables.

For example product class: ProductFactory
For example customer class: CustomerFactory

I don’t understand what is the type of factory pattern here?

Because for each class associated with 1 factory class. I'm thinking its something duplicate. Why we shouldn’t create abstract factory for CustomerFactory, ProductFactory etc?

and also for example:

We can pass AbstractFactory for type checking instead of ProductFactory in ProductRepository class constructor.

So we can avoid tight coupling between ProductRepository and ProductFactory


Abstract Factory class:

namespace Magento\Framework\ObjectManager\Code\Generator;

/**
 * Abstract Factory class 
 */
abstract class AbstractFactory 
{
    /**
     * Object Manager instance
     *
     * @var \Magento\Framework\ObjectManagerInterface
     */
    protected $_objectManager = null;

    /**
     * Instance name to create
     *
     * @var string
     */
    protected $_instanceName = null;


    /**
     * Create class instance with specified parameters
     *
     * @param array $data
     * @return \Magento\Catalog\Model\Product
     */
    public function create(array $data = array())
    {
        return $this->_objectManager->create($this->_instanceName, $data);
    }
}

Abstract Factory implementation:

namespace Magento\Catalog\Model;
use Magento\Framework\ObjectManager\Code\Generator\AbstractFactory;
/**
 * Factory class for @see \Magento\Catalog\Model\Product
 */
class ProductFactory extends AbstractFactory
{

    public function __construct(\Magento\Framework\ObjectManagerInterface $objectManager, $instanceName = '\\Magento\\Catalog\\Model\\Product')
    {

        $this->_objectManager = $objectManager;
        $this->_instanceName = $instanceName;
    }

}

What is the relation between object manager and factory?

There is so much of chaining objects:

  • For example ProductRepository(here we can call it as client) requires Product object.

  • For this its depends on specific ProductFactory object.

  • ProductFactory object depends on ObjectManager object.

  • ObjectManager object depends on Factory Object (here Developer Object).

Off course they are using Interfaces for loose coupling. Still really confusing flow.

Can you someone give in-depth advantages with Magento 2 factory pattern & also how it differs from Magento 1?

2 Answers 2

8
+50

One thing to remember is we auto-generate factory classes ONLY IF YOU DON'T DEFINE ONE YOURSELF. That means, if you need to do some special magic in the factory, you can do so. (E.g. if you want to log every creation of an instance for some reason, write the factory yourself and we won't auto-generate it.) If we used a single abstract factory class for everything, this would not work.

It can also help a bit with debugging - you get to see the real class, can set breakpoints, see more meaningful stack-traces etc.

2
  • may be small gap..for type checking only i want to use abstract class..but whenever passing i want to pass concrete factory class only.
    – sivakumar
    Commented Jul 28, 2015 at 1:35
  • Interesting - I would have considered the other way around. I would want CustomerFactory passed in so I have type hinting that create() will return Customer. With AbstractFactory, I cannot use php Storm type hinting to work out the type of the returned object from the factory. (Or am I missing something?)
    – Alan Kent
    Commented Jul 29, 2015 at 7:14
8

I may be wrong here, but this is an advantage I found.
The auto generated factories are some how similar with the magic getters or setters.
Let's say you want something to happen when an instance of a specific entity (let's call it BlogPost) is created. Let's say you want to set a default value to a field.
The example may not be the best but hear me out.
If you use an abstract factory, you will have to modify it so that when you receive the instanceName as parameter 'BlogPost' you call setDate after instantiating.

If you use autogenerated factory, you can later create that factory, call the setter in your code, remove the generated factory and it will work.
Similar to what you do with the magic setter. You implement the method and it's called everywhere.

2
  • Hi Marius.thanks for your response.agree with you.still need more information.
    – sivakumar
    Commented Jul 27, 2015 at 12:47
  • @sivakumar. I would love an answer from a core team member also.
    – Marius
    Commented Jul 27, 2015 at 12:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.