Ich weiß theoretisch, was eine Proxy-Klasse in Magento 2 ist. Ich habe den großartigen Alan Storm-Artikel darüber gelesen und verstehe vollkommen, wie diese Klassen generiert werden.
Und ich weiß nicht, ob es daran liegt, dass ich kein englischer Muttersprachler bin oder ob Alan in seinen Erklärungen sehr abstrakte Nebenklassen verwendet. Es fällt mir jedoch schwer zu verstehen, wie das funktioniert und wann ich es verwenden soll es während der Entwicklung.
Nehmen wir also dieses Beispiel aus dem Kern von app/code/Magento/GoogleAdwords/etc/di.xml
:
<?xml version="1.0"?>
<!--
/**
* Copyright © 2016 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\GoogleAdwords\Observer\SetConversionValueObserver">
<arguments>
<argument name="collection" xsi:type="object">Magento\Sales\Model\ResourceModel\Order\Collection\Proxy</argument>
</arguments>
</type>
</config>
Ich würde gerne wissen:
- Warum wird in diesem speziellen Fall eine Proxy-Klasse verwendet ?
- Wann sollte man im Allgemeinen eine Proxy-Klasse verwenden?
quelle
Mit einer Proxy-Klasse können Sie eine Klasse abhängig machen, die Sie nicht unbedingt benötigen und die mit hohen Kosten verbunden ist.
Wenn Sie sich einen Proxy ansehen, den Magento generiert hat
\Magento\Framework\View\Layout\Proxy
, werden Sie feststellen, dass er dieselben Methoden wie die ursprüngliche Klasse hat. Der Unterschied besteht darin, dass bei jedem Aufruf überprüft wird, ob die Klasse, von der es sich um einen Proxy handelt, tatsächlich instanziiert wurde, und das Objekt erstellt wird, wenn dies nicht der Fall ist. (Dies geschieht in einer_getSubject()
oder_getCache()
Methode.)Es ist ein fauler Ladevorgang für die Abhängigkeitsinjektion.
Sie sollten einen Proxy verwenden, wenn eine Klassenabhängigkeit nicht immer von Ihrer Klasse verwendet wird.
Ein gutes Beispiel hierfür sind Sitzungen. Es ist eine schlechte Praxis, Sitzungen über den ObjectManager zu erhalten, aber das Injizieren einer Sitzungsklasse wie
\Magento\Customer\Model\Session
könnte zu Problemen führen, wenn Ihre Klasse jemals außerhalb des Gültigkeitsbereichs dieser Sitzung ausgeführt wird (sagen wir, Sie injizieren die Frontend-Kundensitzung auf einer Administrationsseite). Sie umgehen dies, indem Sie\Magento\Customer\Model\Session\Proxy
stattdessen den Proxy der Sitzung injizieren und ihn nur referenzieren, wenn Sie wissen, dass er gültig ist. Wenn Sie nicht darauf verweisen, wird die Sitzung niemals instanziiert und nichts wird unterbrochen.In Ihrem konkreten Beispiel
di.xml
sieht es so aus, als hätten sie den Proxy verwendet, um das Injizieren eines Controllers zu rechtfertigen, und nicht die Fabrik dieses Controllers. In beiden Fällen sind Proxies nicht dafür vorgesehen, und der Nutzen ist in dieser Situation wahrscheinlich minimal.quelle
Autogenerierte Proxys vom Typ Magento 2 können verwendet werden, um Entwurfsfehler zu "beheben". Das kann sehr praktisch sein. Es gibt 2 Anwendungsfälle:
Wickeln Sie einen teuren Objektgraphen ein, der möglicherweise nicht jedes Mal von der abhängigen Person benötigt wird.
Brechen Sie eine zyklische Abhängigkeit, von der die Klasse
A
abhängtB
und von der die KlasseB
abhängtA
.Durch Injizieren
B\Proxy
inA
können Sie eine InstanzA
erstellen, die wiederum verwendet werden kann, um eine Instanz zu erstellen,B
wenn sie tatsächlich mit dem realenA
Objekt verwendet wird.Im Fall von 1. ist die Abhängigkeit, die nicht immer verwendet wird, ein Zeichen dafür, dass die abhängige Klasse zu viel oder möglicherweise zu viel mit einer Methode tut. Der erwähnte Konsolenbefehl @ivan ist ein gutes Beispiel dafür.
Im Fall von 2. Ich kenne keinen generischen Weg, um diese Abhängigkeit aufzulösen. Ich neige dazu, umzuschreiben, wenn Zeit ist, aber das könnte keine Option sein.
Nur als Randnotiz möchte ich hinzufügen, dass es in OOP viel mehr Arten von Proxys gibt als die automatisch generierte verzögerte Instanziierung, die ein Magento 2 verwendet (z. B. Remote-Proxy).
quelle
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
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
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.
Die Proxy-Klasse verfügt über eine Methode zum Erstellen eines Objekts bei Bedarf. _Subject ist das Objekt der übergebenen Klasse.
Und Methode mit _subject aufgerufen.
quelle