Design Patterns in Magento 2 – Object manager

Let’s review this list in more detail by checking the ObjectMagerInterface which is a part of the Magento framework. It is the best way to describe its approach because method implementation is self-explanatory.
But what mechanism is being used for a new object initialization? We think that the patient reader already has an answer to that question. Under the hood, the Object manager uses a factory method pattern to generate a new instance by its type.

While describing the specific pattern, we will use the following structure: its basic explanation, role in the Magento / Adobe Commerce, the most efficient pattern’s applicability and limitations of usage. Such structure should help create a clear understanding of the architecture.

Who is this article for?

Another method represented in the Object manager interface is the get method. This one has the same high value for the platform as the previously described one. According to its declaration, the get method retrieve the cached object instance.

Object manager

General overview

MagentoCatalogModelIndexerCategoryProductAbstractAction

Factory and Proxies are some kinds of exceptions for the direct call of Object manager because they need Object manager to generate new objects. As an example, you can overview any kind of DTO factory.

Method create

/** * Retrieve cached object instance * * @param string $type * @return mixed */ public function get($type);

/** * Configure di instance * Note: All arguments should be pre-processed (sort order, translations, etc) before passing to method configure. * * @param array $configuration * @return void */ public function configure(array $configuration) { $this->_config->extend($configuration); }

/** * Create new object instance * * @param string $type * @param array $arguments * @return mixed */ public function create($type, array $arguments = []);

/** * Test with image. * * @param array $documentData * @param string $sourceFile * @param string $destinationPath * @return void * @dataProvider getSaveTestDataProvider */ public function testSave(array $documentData, string $sourceFile, string $destinationPath): void { $this->deleteImage($destinationPath); $document = $this->getDocument($documentData); $saveImage = Bootstrap::getObjectManager()->create(SaveImageInterface::class); $saveImage->execute( $document, $this->getImageFilePath($sourceFile), $destinationPath ); $this->assertImageSavedToDirectory($destinationPath); $this->assertAssets($destinationPath, $documentData); $this->deleteImage($destinationPath); }

Magic methods

/** * Init not serializable fields * * @return void * @since 100.0.11 */ public function __wakeup() { $objectManager = MagentoFrameworkAppObjectManager::getInstance(); $this->_adapter = $objectManager->get(ResourceConnection::class)->getConnection(); $this->selectRenderer = $objectManager->get(MagentoFrameworkDBSelectSelectRenderer::class); }

It may sound strange to talk about usage and start an explanation with limitations but it has a total sense. Object manager direct usage in the application is dangerous because it breaks the idea of atomate object generation based on the type and object parameters declaration. Remember that the create method in the Object manager implementation uses the factory method which by its origin requires only object name  (type).
The last one in the list but the first by platform calls. Its declaration is simple:
/** * Retrieve cached object instance * * @param string $type * @return mixed */ public function get($type) { $type = ltrim($type, ‘\’); $type = $this->_config->getPreference($type); if (!isset($this->_sharedInstances[$type])) { $this->_sharedInstances[$type] = $this->_factory->create($type); } return $this->_sharedInstances[$type]; }

/** * Configure object manager * * @param array $configuration * @return void */ public function configure(array $configuration);

/** * Create new object instance * * @param string $type * @param array $arguments * @return mixed */ public function create($type, array $arguments = []) { return $this->_factory->create($this->_config->getPreference($type), $arguments); }

We are happy to introduce a series of articles dedicated to design patterns of Magento 2 architecture. Explanation of their roles in the architecture of the e-commerce platform will help understand not only Magento 2 website design, but shall also make a beneficial impact on developing new business components.

Object manager usage

Direct call

Magento / Adobe Commerce is a well-known e-commerce platform with the performance record of more than 10 years. From the first release of Magento 1 to the latest revision of Magento 2, its main advantage is the number of business processes automated from the box: catalog, sales and marketing, along with other numerous features. To ensure flexible communication between components and to provide the ability for efficient customization, Magento 2 has developed a complex architecture which is based on a combination of design patterns.

Factory and proxies

The material we present in these articles is for developers of all levels of expertise, solution architects and those who want to learn more details about the Magento / Adobe Commerce design.

Backwards compatibility

The first method we find in the interface is create.
First, we decided to describe Object manager because it plays a leading role in the majority of the Magento 2 / Adobe Commerce aspects. According to the official documentation, Object manager is responsible for:
<argument xsi:type=”object” shared=”{shared}”>{typeName}</argument>

Sometimes it is required to add a new parameter to the object constructor and to follow backwards compatibility rules a newly added object has to be declared with the help of the Object manager. For example,