0

I figured out that magento 2 uses a proxy class which then creates an instance of a class. I don't understand why this proxy class is used, whats the advantage of it? Why not just creating the instance normally like always?

Example:

vendor\magento\module-catalog\Model\Product\Link.php:

public function __construct(
    ...
    \Magento\Catalog\Model\ResourceModel\Product\Link\Product\CollectionFactory $productCollectionFactory,
    ...
    array $data = []
) {
    ...
    $this->_productCollectionFactory = $productCollectionFactory;
    ...
}

public function getProductCollection()
{
    $collection = $this->_productCollectionFactory->create()->setLinkModel($this);
    return $collection;
}

The method create() from $this->_productCollectionFactory->create() is defined in generated\code\Magento\Catalog\Model\ResourceModel\Product\Link\Product\CollectionFactory.php:

public function create(array $data = [])
{
    return $this->_objectManager->create($this->_instanceName, $data);
}

It uses objectManager to create the object from the class defined in $this->_instanceName which is \Magento\Catalog\Model\ResourceModel\Product\Link\Product\Collection

This looks totaly complicated and unecessary, why all this trouble? Why not just creating the object directly from start in the constructor:

public function __construct(
    ...
    \Magento\Catalog\Model\ResourceModel\Product\Link\Product\Collection $productCollection,
    ...
    array $data = []
) {
    ...
    $this->_productCollection = $productCollection;
    ...
}

public function getProductCollection()
{
    $collection = $this->_productCollection->setLinkModel($this);
    return $collection;
}

Please help me to understand the advantage of the factory way.

1

We use proxy in Magento 2 when we are trying to delay the instance to be loaded. some class do not incur any data to load and some do

If you have a class that has some dependency to it and some of these dependencies can load data when their constructor is called, that would incur an overhead in your class if you need the class but yet you don't want the data to be loaded.

When a class has data (eg: customer, product, order..), I was recommended to use factory.

I did check the class you mention to convince myself of the load impact

you may follow the code trail as below:

1. \Magento\Catalog\Model\ResourceModel\Product\Link\Product\Collection
2. \Magento\Catalog\Model\ResourceModel\Product\Collection::__construct
3. \Magento\Catalog\Model\ResourceModel\Collection\AbstractCollection::__construct
4. \Magento\Eav\Model\Entity\Collection\AbstractCollection::__construct
in this constructor, we have the line $this->_prepareStaticFields(); loading  data. 

This function is likely one amongst more if you were to contemplate this constructor more thoroughly. However, as an architecture point of view, even if your class may seem pretty much light to load, it may not be the case on further Magento releases and it is for this reason important to use the factory to prevent unnecessary code to be triggered..

| improve this answer | |
  • Thank you! If I understand you correctly then we should use proxies for performance reasons. We don't instantiate the full class from start, because this would take too long to load, so we only create an instance to the full class if we really need it. So at start we only create an instance to the factory class, which is very minimalistic and only has the create() method, so that we can create an instance to the full class later on, but only if we need it. – Black May 13 at 12:09
  • 1
    yes, now, of course you can also create your model using proxy too. I used in my case a lot of lazy load functions when I write code.. But in fact, I have been told lazy functions can lead to bug that are complex to debug.. whilst I explain this to you, I would benefit from proxy if I was loaded the content of my lazy load method in my constructor – Herve Tribouilloy May 13 at 12:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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