Introduction
Magento2 introduced us with many design patterns, I have also discussed some of them in my previous articles:
Today we will be discussing another design pattern Object Pool Design pattern and how it is used in magento2.
Object pools are set of objects that you don’t need to create or destroy, these objects are automatically available in your code pool, so you just need to use them.
What is the need of Object Pool?
- you don’t need to create or destroy objects, they will be available by default.
- objects will not be loaded at the time of class loading, they will be only loaded when it will be demanded.
- object pools are very useful where you want to allow other modules to add there your own data, without having to make any changes in the core files, like config providers of the payment methods in magento2.
Let’s take an example of payment methods config provider:
If you are building a payment method, you need to write some knockout js code to make it available on the checkout page, we have already a blog on this:
And as most of you know, whom are working on magento2, you cannot mix knockout js templates with php since they are pure js and html files, so how to get the payment method configuration on the checkout page, since there can be many payment methods that are built by different vendors, so how Magento will know, what data they all want to use in their payment method, since checkout page is same for all the methods it is pure knockout based, to resolve this issue magento2 uses object pool pattern here, now lets see how, below in magento2 checkout module class vendor/magento/module-checkout/Model/CompositeConfigProvider.php:
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Checkout\Model; /** * Composite checkout configuration provider. * * @see \Magento\Checkout\Model\ConfigProviderInterface * @api * @since 100.0.2 */ class CompositeConfigProvider implements ConfigProviderInterface { /** * @var ConfigProviderInterface[] */ private $configProviders; /** * @param ConfigProviderInterface[] $configProviders * @codeCoverageIgnore */ public function __construct( array $configProviders ) { $this->configProviders = $configProviders; } /** * {@inheritdoc} */ public function getConfig() { $config = []; foreach ($this->configProviders as $configProvider) { $config = array_merge_recursive($config, $configProvider->getConfig()); } return $config; } }
The above class is responsible to provide all the payment methods configurations to checkout page, when you will see the get config method it iterate through this property $this->configProviders, basically this is an array of objects, it iterates through all the objects and calls the getConfig method, and getConfig method probably returns an array and all these arrays are merged together and returned to the checkout view, where it is converted in json and set to a window scoped javascript variable so it can be accessed on whole checkout page. You can check this in this file vendor/magento/module-checkout/view/frontend/templates/onepage.phtml, but that’s not our concern, we still have a doubt about $this->configProviders, I am creating a payment method how do I am going to add my configuration object in this property, if you are working on magento2 you will all know using di.xml file, lets see the frontend di.xml file of checkout module:
<type name="Magento\Checkout\Model\CompositeConfigProvider"> <arguments> <argument name="configProviders" xsi:type="array"> <item name="checkout_default_config_provider" xsi:type="object">Magento\Checkout\Model\DefaultConfigProvider</item> </argument> </arguments> </type>
you can see in the above xml there is a default checkout config provider, which will be added to the configProviders property of the CompositeConfigProvider class at the time of class instantiation, similarly any configuration you want to add at checkout page, simply create a frontend di.xml file and and the above type declaration and add your item in the configProviders array.
This is one example of object pool and its benifits, magento2 uses a lot of object pools, you might be seeing and using this for a long time without knowing how it works, but may be now you can understand.
Let me know if you have any doubts in the above explanation, Thanks 🙂
Thanks for this post.
Is there some conflicts in terminology in comparing with original Object Pool description? For me it looks more like Factory.
Even this data provider named like a factory MagentoFrameworkViewElementUiComponentDataProviderCollectionFactory. But it works like “Magento Object Pool”.
One of an important description for me (https://en.wikipedia.org/wiki/Object_pool_pattern) which doesn’t match:
The object pool design pattern creates a set of objects that may be reused. When a new object is needed, it is requested from the pool. If a previously prepared object is available it is returned immediately, avoiding the instantiation cost. If no objects are present in the pool, a new item is created and returned. When the object has been used and is no longer needed, it is returned to the pool, allowing it to be used again in the future without repeating the computationally expensive instantiation process. It is important to note that once an object has been used and returned, existing references will become invalid.
Maybe exact “pools” follow the main goal of pattern but Magento 2 has lots of “pools”.