Итак, я теоретически знаю, что такое прокси-класс в Magento 2. Я прочитал об этом замечательную статью об Alan Storm и полностью понимаю, как создаются эти классы.
Тем не менее, и я не знаю, потому ли это, что я не являюсь носителем английского языка или в объяснениях Алана используются неосновные классы, которые являются очень абстрактными, но мне трудно понять, как это работает и особенно когда использовать это во время разработки.
Итак, давайте возьмем этот пример из ядра в 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>
Я бы хотел знать:
- почему прокси-класс используется в этом конкретном случае?
- когда вообще следует использовать прокси-класс?
источник
Прокси-класс позволяет вам вводить зависимые классы, которые вам не обязательно нужны, и это связано с большими затратами.
Если вы посмотрите на прокси, сгенерированный Magento
\Magento\Framework\View\Layout\Proxy
, вы увидите, что он имеет все те же методы, что и исходный класс. Разница в том, что каждый раз, когда вызывается какой-либо из них, он проверяет, был ли создан экземпляр класса, для которого он является прокси, и создает объект, если нет. (Это происходит в_getSubject()
или_getCache()
метод.)Это ленивая загрузка для внедрения зависимости.
Вы должны использовать прокси, если зависимость класса не всегда используется вашим классом, и:
Один хороший пример этого - сессии. Получение сессий с помощью ObjectManager - плохая практика, но внедрение такого сессионного класса
\Magento\Customer\Model\Session
может привести к поломке, если ваш класс когда-либо выйдет за пределы области действия этого сеанса (скажем, вы внедрите сеанс клиента внешнего интерфейса на странице администратора). Вы можете обойти это, введя\Magento\Customer\Model\Session\Proxy
вместо этого прокси-сервер сеанса и ссылаясь на него, только когда знаете, что он действителен. Если вы не ссылаетесь на него, сеанс никогда не создается, и ничего не нарушается.В вашем конкретном примере
di.xml
похоже, что они использовали прокси-сервер для оправдания введения контроллера, а не для фабрики этого контроллера. В любом случае, это не то, для чего предназначены прокси, и выгода от этого в этой ситуации, вероятно, минимальна.источник
Автоматически сгенерированные прокси типа Magento 2 можно использовать для «исправления» ошибок проектирования. Это может быть очень удобно. Есть 2 варианта использования:
Оберните дорогой объектный граф, который может не понадобиться каждый раз зависимому лицу.
Прервите циклическую зависимость, где класс
A
зависит от,B
а классB
зависит отA
.Инъекция
B\Proxy
вA
позволяет вам создавать экземплярыA
, которые затем, в свою очередь, могут использоваться для создания экземпляров,B
когда они фактически используются с реальнымA
объектом.В случае 1. зависимость, которая не всегда используется, является признаком того, что класс зависимых делает много или, возможно, делает много одним методом. Упомянутая консольная команда @ivan - хороший тому пример.
В случае 2. Я не знаю общего способа сломать эту зависимость. Я склонен переписывать, если есть время, но это не может быть вариантом.
В качестве дополнительного примечания я хотел бы добавить, что в ООП существует намного больше типов прокси, чем автоматическое создание ленивых экземпляров, которое использует Magento 2 (например, удаленный прокси).
источник
Вот ответы
почему прокси-класс используется в этом конкретном случае?
Если вы внимательно посмотрите ниже код, который написан для класса «SetConversionValueObserver», если Google Adwards не активен «возврат» и если нет порядка «возврат». Значит, Объект сбора заказов будет создан только тогда, когда существуют идентификаторы заказов и активны Google AdWords. если мы добавим фактический класс коллекции Order, то менеджер объектов создаст объект коллекции с объектами родительского класса, не зная, что Google AdWords не активен, и это замедлит страницу успеха заказа. Итак, лучше создать объект по требованию, то есть использование прокси. /vendor/magento/module-google-adwords/Observer/SetConversionValueObserver.php
когда вообще следует использовать прокси-класс? - Введите класс Proxy, когда вы чувствуете, что создание объекта будет дорогостоящим, а конструктор класса особенно ресурсоемким. - когда вы не хотите ненужного влияния на производительность из-за создания объекта. - когда вы чувствуете, что создание объекта должно происходить, когда вы не всегда вызываете определенный метод в определенном состоянии. Например, конструктор Layout является ресурсоемким.
Фактический конструктор макетов против макета / прокси
Прокси-конструктор, посмотрите, родительский конструктор не вызван, а только что передан имя класса макета, так что фактическое создание объекта происходит при вызове метода.
Прокси-класс имеет метод для создания объекта по требованию, _subject является объектом переданного класса.
И метод вызывается с помощью _subject.
источник