Hier sind die Antworten
Warum wird in diesem speziellen Fall eine Proxy-Klasse verwendet?
Wenn Sie den folgenden Code, der für die Klasse "SetConversionValueObserver" geschrieben wurde, genau betrachten, wenn Google Adwards nicht aktiv ist, "return" und wenn es keine Bestellung gibt, "return". Das bedeutet, dass das Auftragserfassungsobjekt nur erstellt wird, wenn Auftrags-IDs vorhanden und Google AdWords aktiv sind. Wenn wir die tatsächliche Auftragserfassungsklasse einfügen, erstellt der Objektmanager ein Erfassungsobjekt mit seinen übergeordneten Klassenobjekten, ohne zu wissen, dass Google AdWords nicht aktiv ist und die Seite mit dem Auftragserfolg verlangsamt. Erstellen Sie daher besser ein Objekt nach Bedarf, das die Verwendung eines Proxys ist. /vendor/magento/module-google-adwords/Observer/SetConversionValueObserver.php
/**
* Set base grand total of order to registry
*
* @param \Magento\Framework\Event\Observer $observer
* @return \Magento\GoogleAdwords\Observer\SetConversionValueObserver
*/
public function execute(\Magento\Framework\Event\Observer $observer)
{
if (!($this->_helper->isGoogleAdwordsActive() && $this->_helper->isDynamicConversionValue())) {
return $this;
}
$orderIds = $observer->getEvent()->getOrderIds();
if (!$orderIds || !is_array($orderIds)) {
return $this;
}
$this->_collection->addFieldToFilter('entity_id', ['in' => $orderIds]);
$conversionValue = 0;
/** @var $order \Magento\Sales\Model\Order */
foreach ($this->_collection as $order) {
$conversionValue += $order->getBaseGrandTotal();
}
$this->_registry->register(
\Magento\GoogleAdwords\Helper\Data::CONVERSION_VALUE_REGISTRY_NAME,
$conversionValue
);
return $this;
}
Wann sollte man im Allgemeinen eine Proxy-Klasse verwenden?
- Injizieren Sie die Proxy-Klasse, wenn Sie der Meinung sind, dass die Objekterstellung teuer ist und der Konstruktor der Klasse besonders ressourcenintensiv ist. - wenn Sie keine unnötigen Leistungseinbußen aufgrund der Objekterstellung wünschen. - Wenn Sie der Meinung sind, dass die Objekterstellung stattfinden sollte, wenn Sie eine bestimmte Methode in einer bestimmten Bedingung nicht immer aufrufen. Beispielsweise ist der Layoutkonstruktor ressourcenintensiv.
Tatsächlicher Layoutkonstruktor vs. Layout / Proxy
public function __construct(
Layout\ProcessorFactory $processorFactory,
ManagerInterface $eventManager,
Layout\Data\Structure $structure,
MessageManagerInterface $messageManager,
Design\Theme\ResolverInterface $themeResolver,
Layout\ReaderPool $readerPool,
Layout\GeneratorPool $generatorPool,
FrontendInterface $cache,
Layout\Reader\ContextFactory $readerContextFactory,
Layout\Generator\ContextFactory $generatorContextFactory,
AppState $appState,
Logger $logger,
$cacheable = true,
SerializerInterface $serializer = null
) {
$this->_elementClass = \Magento\Framework\View\Layout\Element::class;
$this->_renderingOutput = new \Magento\Framework\DataObject();
$this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class);
$this->_processorFactory = $processorFactory;
$this->_eventManager = $eventManager;
$this->structure = $structure;
$this->messageManager = $messageManager;
$this->themeResolver = $themeResolver;
$this->readerPool = $readerPool;
$this->generatorPool = $generatorPool;
$this->cacheable = $cacheable;
$this->cache = $cache;
$this->readerContextFactory = $readerContextFactory;
$this->generatorContextFactory = $generatorContextFactory;
$this->appState = $appState;
$this->logger = $logger;
}
Proxy-Konstruktor, werfen Sie einen Blick, es wird kein übergeordneter Konstruktor aufgerufen und nur der Name der Layout-Klasse übergeben, sodass die eigentliche Objekterstellung beim Aufruf der Methode erfolgt.
/**
* Proxy constructor
*
* @param \Magento\Framework\ObjectManagerInterface $objectManager
* @param string $instanceName
* @param bool $shared
*/
public function __construct(
\Magento\Framework\ObjectManagerInterface $objectManager,
$instanceName = \Magento\Framework\View\Layout::class,
$shared = true
) {
$this->_objectManager = $objectManager;
$this->_instanceName = $instanceName;
$this->_isShared = $shared;
}
Die Proxy-Klasse verfügt über eine Methode zum Erstellen eines Objekts bei Bedarf. _Subject ist das Objekt der übergebenen Klasse.
/**
* Get proxied instance
*
* @return \Magento\Framework\View\Layout
*/
protected function _getSubject()
{
if (!$this->_subject) {
$this->_subject = true === $this->_isShared
? $this->_objectManager->get($this->_instanceName)
: $this->_objectManager->create($this->_instanceName);
}
return $this->_subject;
}
Und Methode mit _subject aufgerufen.
/**
* {@inheritdoc}
*/
public function setGeneratorPool(\Magento\Framework\View\Layout\GeneratorPool $generatorPool)
{
return $this->_getSubject()->setGeneratorPool($generatorPool);
}