magento2对象管理器-ObjectManager

7天成为Magento系统架构师,现在开始学习Magento全栈开发!

《Magento2.X企业级开发实战》

magento2对象管理器-ObjectManager

Magento 2 为经验丰富的 Magento 1 程序员带来了一系列变化。虽然你仍然可以看到 Magento 1 的点点滴滴(EAV、区域、块等),但新的 Magento 2 核心团队在过去几年里已经用更成熟的“企业-java”风格的系统。更多的类、更多的对象和更多的设计模式。

尽管有些人可能认为代码复杂性增加了,但 Magento 2 核心团队也花了很多时间来简化和阐明 Magento 1 中的想法。 Magento 1 的本土类重写系统——基于块、模型和助手——已经替换为基辅增长的依赖注入容器/对象管理器系统。

如果您的 Magento 1 开发方法是复制粘贴、食谱风格的开发,那么 Magento 2 就所有意图和目的而言都是一个新框架。你的旧咒语将不再有效。

但是,如果您对 Magento 1 开发的方法是理解设计模式的实现,并培养阅读代码的能力,那么在 Magento 2 上加速将是道路上的一个小障碍——而且在许多方面应该使开发变得更稳定、更可预测的事情。

这篇文章是解释 Magento 2 的对象管理器/依赖注入系统的系列文章中的第一篇。我们将探索程序员(您!)如何在 Magento 2 中创建对象,探索 Magento 2 的对象系统带来的附加功能,并在此过程中我们将讨论 Magento 1 的变化并开始探索 Magento 的约定2

与 Magento 1 相同,模块的全名来自其“命名空间”文件夹和“模块名称”文件夹的组合。 但是,这里有一些事情可能会使 Magento 1 开发人员陷入循环。 具体来说

Magento 的模块命名空间现在是 Magento_ 而不是 Mage_
核心、社区和本地代码池都消失了。 所有模块都存在于应用程序/代码中

在我看来,Magento 到 Mage 的变化是一个中立的变化,但是删除代码池和模块声明文件对 Magento 来说是积极的。

虽然核心、社区和本地代码池/包含文件夹允许系统所有者通过代码池覆盖对 Magento 功能进行快速更改,但这些文件在很大程度上导致商家不愿意升级他们的系统,并经常导致微妙的系统问题当开发人员会更改太多类文件的隐式约定时。

app/etc/modules 中模块声明文件的丢失——虽然是一个有趣想法的一部分(整个系统的一个全局配置)——不会被错过。虽然这些文件的最初意图可能是配置哪些模块应该或不应该在系统中启用,但糟糕的早期开发人员布道和核心团队实践意味着扩展开发人员开始将这些文件与他们的扩展一起打包,以及任何希望其中用户可配置的文件被排除在外。简单的开/关配置阵列的 Magento 2 方法更有意义。

首先,让我们回顾一些 PHP 101。当您想在 PHP 中实例化一个对象时,您可以使用 new 关键字。 让我们在我们的 execute 方法中尝试一下

protected function execute(InputInterface $input, OutputInterface $output)
{
    $object = new \Pulsestorm\TutorialObjectManager1\Model\Example;
    $message = $object->getHelloMessage();
    $output->writeln(
        $message
    );                
}    

当您想在 PHP 中实例化一个对象时,您可以使用 new 关键字。 让我们在我们的 execute 方法中尝试一下 …

#File: app/code/Pulsestorm/TutorialObjectManager1/Command/Testbed.php    
protected function execute(InputInterface $input, OutputInterface $output)
{
    $manager = $this->getObjectManager();
    $object  = $manager->create('Pulsestorm\TutorialObjectManager1\Model\Example');
    $message = $object->getHelloMessage();
    $output->writeln(
        $message
    );                
}  

这段新代码和我们旧代码的最大区别是这两行

第一个,$manager = $this->getObjectManager();,为我们获取对象管理器。 这不是您在编写 Magento 2 扩展时通常会做的事情 — getObjectManager 是我们为本教程添加的辅助方法。 我们稍后会回到这个概念,但现在接受 getObjectManager 将返回 Magento 对象管理器的一个实例。

对象管理器是一个特殊的对象,Magento 用它来实例化几乎所有的对象。 这就是我们在第二行所做的

#File: app/code/Pulsestorm/TutorialObjectManager1/Command/Testbed.php    
$object  = $manager->create('Pulsestorm\TutorialObjectManager1\Model\Example');

我们调用了对象管理器的 create 方法,并将 PHP 类名作为字符串传入。 在幕后,对象管理器为我们实例化了一个 Pulsestorm\TutorialObjectManager1\Model\Example。

最简单的形式就是 Magento 2 的对象管理器。 这似乎是一个微不足道的区别,但是通过通过这个单一点路由所有对象实例化,Magento 系统工程师能够赋予他们的对象许多“超能力”。

在我们获得超能力之前,虽然完全覆盖它超出了本文的范围,但 Magento 对象管理器的源代码在以下类文件中。

#File: lib/internal/Magento/Framework/ObjectManager/ObjectManager.php
namespace Magento\Framework\ObjectManager;

class ObjectManager implements \Magento\Framework\ObjectManagerInterface
{
    //...    
}

如果您是 Magento 1 开发人员,对象管理器是这三种方法的替代品

Mage::getModel(...);
Mage::helper(...);
Mage::getSingleton('core/layout')->createBlock(...);    

虽然 Magento 2 仍然有模型、助手和块的概念,但您不再需要知道这些对象(核心/模板、模型/产品等)的类别名,对象管理器可以实例化任何 PHP 类,而不仅仅是模型、助手或块对象。

自动单例对象
我们将通过讨论 Magento 的对象管理器赋予对象的一种超能力来结束今天的工作——自动单例。 不过,在我们这样做之前,我们可能应该描述一下我们所说的单例是什么意思!

尝试运行以下代码

#File: app/code/Pulsestorm/TutorialObjectManager1/Command/Testbed.php
protected function execute(InputInterface $input, OutputInterface $output)
{
    $manager = $this->getObjectManager();
    $object  = $manager->create('Pulsestorm\TutorialObjectManager1\Model\Example');        
    $object->message = 'Hello PHP!';
    $output->writeln(
        $object->getHelloMessage()
    );                

    $object  = $manager->create('Pulsestorm\TutorialObjectManager1\Model\Example');        
    $output->writeln(
        $object->getHelloMessage()
    );                        
}

此代码与我们之前的示例类似,但有一些补充。 首先,我们使用对象管理器从 Pulsestorm\TutorialObjectManager1\Model\Example 类中实例化一个对象

#File: app/code/Pulsestorm/TutorialObjectManager1/Command/Testbed.php    

$object  = $manager->create('Pulsestorm\TutorialObjectManager1\Model\Example'); 

然后我们为对象设置一个自定义的消息字符串

然后我们使用 cli 框架的 writeln 方法输出新消息。

#File: app/code/Pulsestorm/TutorialObjectManager1/Command/Testbed.php    

$output->writeln(
    $object->getHelloMessage()
);                

这是第一段代码。 在第二段代码中

#File: app/code/Pulsestorm/TutorialObjectManager1/Command/Testbed.php    

$object  = $manager->create('Pulsestorm\TutorialObjectManager1\Model\Example');        
$output->writeln(
    $object->getHelloMessage()
);                        

我们实例化了一个新的 Pulsestorm\TutorialObjectManager1\Model\Example 对象,然后输出它的默认消息。 这意味着我们的程序输出

现在,让我们尝试完全相同的代码,除了不使用对象管理器的 create 方法,我们将使用对象管理器的 get 方法

#File: app/code/Pulsestorm/TutorialObjectManager1/Command/Testbed.php    

protected function execute(InputInterface $input, OutputInterface $output)
{
    $manager = $this->getObjectManager();
    $object  = $manager->get('Pulsestorm\TutorialObjectManager1\Model\Example');        
    $object->message = 'Hello PHP!';
    $output->writeln(
        $object->getHelloMessage()
    );                

    $object  = $manager->get('Pulsestorm\TutorialObjectManager1\Model\Example');        
    $output->writeln(
        $object->getHelloMessage()
    );                        
}

我们的程序没有第二次打印默认消息,而是打印了我们在第一个对象上设置的相同自定义消息。 为什么会这样? 因为第二个对象是第一个对象。

这是 Magento 对象管理器的“自动单例”功能。 如果你不熟悉这个概念——单例是一个只能实例化一次的对象。 对于单例,以后尝试实例化同一对象将返回原始实例。 这在传统上是通过向类的构造函数添加特殊代码来实现的——但是使用 Magento 2 的对象管理器,任何类都可以变成单例对象。

回到我们上面的代码示例,我们第二次调用 get Magento 返回带有自定义消息集的原始对象。

如果您来自 Magento 1,则创建/获取差异类似于

Mage::getModel(...);
Mage::getSingleton(...);

自动单例只是 Magento 2 的对象管理器赋予其对象的超能力之一。 下次我们将讨论强大的超能力——自动构造函数参数依赖注入——我们还将揭示为什么 Magento 的文档(看似自相矛盾)告诉你不要使用对象管理器。

如无特殊说明或标注,任何个人或组织,复制、转载、采集本站内容请注明:
本文来源于:【Magento中文网】,并添加本文地址链接。
如未按上述操作复制或转载,本站有权追究法律责任。
若本站内容侵犯了原著者的合法权益,可联系我们进行处理。