Wiem więc teoretycznie, czym jest klasa proxy w Magento 2. Przeczytałem o niej niesamowity artykuł Alan Storm i całkowicie rozumiem, w jaki sposób te klasy są generowane.
Jednak i nie wiem, czy to dlatego, że nie jestem rodzimym językiem angielskim, czy też wyjaśnienia Alana używają nie-podstawowych klas, które są bardzo abstrakcyjne, ale trudno mi zrozumieć, jak to działa, a zwłaszcza kiedy używać to podczas rozwoju.
Weźmy ten przykład z rdzenia w 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>
Chciałbym wiedzieć:
- dlaczego w tym konkretnym przypadku używana jest klasa proxy ?
- kiedy ogólnie należy używać klasy proxy?
źródło
Klasa proxy pozwala wstrzykiwać zależności, które niekoniecznie będą potrzebne, a to wiąże się z wysokimi kosztami.
Jeśli spojrzysz na serwer proxy wygenerowany przez Magento,
\Magento\Framework\View\Layout\Proxy
zobaczysz, że ma wszystkie te same metody, co klasa oryginalna. Różnica polega na tym, że za każdym razem, gdy którekolwiek z nich jest wywoływane, sprawdza, czy klasa, której jest proxy, faktycznie została utworzona, i tworzy obiekt, jeśli nie. (Dzieje się tak w metodzie_getSubject()
lub_getCache()
).Leniwe ładowanie do wstrzykiwania zależności.
Powinieneś użyć serwera proxy, jeśli klasa nie zawsze używa zależności od klasy i:
Dobrym tego przykładem są sesje. Uzyskiwanie sesji przez ObjectManager to zła praktyka, ale wstrzykiwanie klasy sesji, tak jak
\Magento\Customer\Model\Session
mogłoby to zepsuć, jeśli twoja klasa kiedykolwiek działa poza zakresem tej sesji (powiedz, że wstrzykujesz sesję klienta frontonu na stronie administratora). Można obejść ten\Magento\Customer\Model\Session\Proxy
problem , wstrzykując zamiast tego serwer proxy sesji i odwołując się do niego tylko wtedy, gdy wiesz, że jest prawidłowy. O ile nie odwołujesz się do niego, sesja nigdy nie jest tworzona i nic się nie psuje.W twoim konkretnym przykładzie
di.xml
wygląda na to, że użyli proxy do uzasadnienia wstrzyknięcia kontrolera, a nie fabryki tego kontrolera. Tak czy inaczej, nie do tego służą proxy, a korzyść z tego w tej sytuacji jest prawdopodobnie minimalna.źródło
Automatycznie generowane serwery proxy typu Magento 2 mogą być używane do „naprawy” błędów projektowych. To może być bardzo przydatne. Istnieją 2 przypadki użycia:
Zawiń kosztowny wykres obiektowy, który może nie być potrzebny każdorazowo przez osobę zależną.
Przerwij cykliczną zależność, w której klasa
A
zależy od,B
a klasaB
zależy odA
.Wstrzykiwanie
B\Proxy
doA
umożliwia tworzenie instancjiA
, która z kolei może być używana do tworzenia instancji,B
gdy jest ona rzeczywiście używana z rzeczywistymA
obiektem.W przypadku 1. zależności, która nie zawsze jest używana, jest to znak, że klasa osób zależnych robi za dużo, a może za dużo jedną metodą. Wspomniane polecenie konsoli @ivan jest tego dobrym przykładem.
W przypadku 2. Nie znam ogólnego sposobu na przełamanie tej zależności. Mam tendencję do przepisywania, jeśli jest czas, ale może to nie być opcja.
Na marginesie, chciałbym dodać, że w OOP jest o wiele więcej typów serwerów proxy niż automatycznie generowana leniwa instancja używana przez Magento 2 (np. Zdalne proxy).
źródło
Oto odpowiedzi
dlaczego w tym konkretnym przypadku używana jest klasa proxy?
Jeśli przyjrzysz się uważnie kodowi napisanemu dla klasy „SetConversionValueObserver”, jeśli Google Adwards nie jest aktywne „return” i jeśli nie ma zamówienia „return”. Oznacza to, że obiekt kolekcji zamówień zostanie utworzony tylko wtedy, gdy istnieją identyfikatory zamówień i aktywne są adwords Google. jeśli wstrzykniemy rzeczywistą klasę kolekcji zamówień, menedżer obiektów utworzy obiekt kolekcji z obiektami klasy nadrzędnej, nie wiedząc, że Google adwords jest nieaktywny i że strona spowalniająca zamówienie jest wolniejsza. więc lepiej tworzyć obiekty na żądanie, czyli korzystanie z proxy. /vendor/magento/module-google-adwords/Observer/SetConversionValueObserver.php
kiedy ogólnie należy używać klasy proxy? - Wstrzyknij klasę Proxy, gdy uważasz, że tworzenie obiektów będzie kosztowne, a konstruktor klasy wymaga dużych nakładów. - gdy nie chcesz niepotrzebnego wpływu na wydajność z powodu tworzenia obiektów. - gdy czujesz, że tworzenie obiektu powinno nastąpić, gdy wywołasz określoną metodę w określonym stanie, nie zawsze. Na przykład Konstruktor układu wymaga dużych zasobów.
Rzeczywisty konstruktor układu a układ / serwer proxy
Konstruktor proxy, spójrz, nie wywoływano żadnego konstruktora nadrzędnego, a także przekazano nazwę klasy układu, aby rzeczywiste tworzenie obiektu miało miejsce po wywołaniu metody.
Klasa proxy ma metodę tworzenia obiektu na żądanie, _subject jest obiektem przekazywanej klasy.
I metoda wywołana przy użyciu _subject.
źródło