Переписывание Magento 2 класса против плагинов

17

В Magento 2 есть концепция плагинов / перехватов / перехватчиков, в отличие от Magento 1.
Они действуют как событие перед | после события для каждого открытого метода. Что приятно.
Вы также можете использовать aroundплагин, чтобы заменить функциональность метода.
Но Magento 2 все еще предлагает возможность переписать классы более или менее способом M1.
Я хотел бы увидеть некоторые примеры, где переписывание классов - это путь вместо использования плагинов.
Я знаю, что это полезно, когда вы хотите изменить поведение основного защищенного метода, но есть ли другие случаи, когда переписывание рекомендуется или необходимо?

Мариус
источник
1
Связанный: magento.stackexchange.com/questions/93932/…
Робби Аверилл

Ответы:

19

Очевидная причина использовать перезапись вместо плагина, когда вам нужно переопределить закрытый, защищенный или финальный метод .

Но также рассмотрим следующие сценарии.

1-й сценарий (абсолютный порядок сортировки):

Переписывание может быть полезно, когда вам нужно, чтобы ваш код запускался перед плагинами . Я знаю, что вы можете сделать это, установив плагин sortOrder, но вы не можете быть уверены, что ваш код всегда будет первым, когда кто-то (не вы) собирается установить сторонние компоненты.

2-й сценарий (исключите код):

Если вам нужно исключить или переписать только часть кода в методе, плагин может быть неоптимальным способом. Я знаю, что вы можете использовать aroundплагин и избегать вызова proceed, но это может сломать другие плагины в стеке.

3-й сценарий (стиль кода):

Вы должны использовать перезапись, когда вам нужно переписать поведение, плагины должны использоваться для изменения вывода или выполнения кода до / после.

Плагин, всегда должен запускать оригинальный код, чтобы не сломать другие модули.

Мой вывод:

Если вы можете рассматривать основной метод как черный ящик с входом и одним выходом, и вы не осведомлены о его внутренних механизмах, тогда плагин может быть лучшим вариантом.

Если вам нужно изменить внутреннее поведение , лучшим вариантом будет перезапись.

Phoenix128_RiccardoT
источник
1-й сценарий немного неточен (я думаю, что это только формулировка), поскольку плагин before или arround запускается (или может запускаться) перед фактическим кодом метода.
Дэвид Верхолен
Да, моя формулировка была неверной. Моя точка зрения была об относительном порядке сортировки с фактическим методом.
Phoenix128_RiccardoT
7

Отличный вопрос, я задал себе то же самое на днях, и вот что я придумал:

  • Во-первых, плагины нельзя использовать для финальных методов, финальных классов и классов, созданных без внедрения зависимостей. Я считаю, что это очень специфический случай, но это тот случай, когда вы не можете использовать плагины.
  • Во-вторых, вы должны иметь в виду определение плагина. Он используется для работы на уровне метода, тогда как предпочтения используются для работы на уровне всего класса. Это не очевидно для всех, поэтому хорошо иметь это в виду.
  • Наконец, и я считаю, что это самое главное, похоже, что плагины могут использоваться только для расширения поведения любого открытого метода в классе Magento . Таким образом, кажется, что вы не можете использовать плагины с защищенными / приватными методами .

Источник: Magento U Фундаментальный курс

Рафаэль в цифровом пианизме
источник
2
Ok. Хорошие причины. Я не знаю, что сказать о втором пункте, хотя. Если вы хотите подключить множество открытых методов из одного и того же класса, я думаю, что самый безопасный способ - создать один класс, который будет работать как плагин для всех них. (мое мнение). Я оставлю это открытым в течение 2-3 дней, чтобы посмотреть, придет ли кто-то по другим причинам. Если нет .... галочка ваша.
Мариус
@Marius, вы абсолютно правы: вторая точка. По некоторым причинам я подумал, что вам нужно создать несколько файлов плагинов для каждого метода, который вы хотите подключить, но я думаю, что это делают наблюдатели, а не плагины. Было бы здорово, если бы больше людей ответили, чтобы увидеть, есть ли еще причины (неочевидные).
Рафаэль на цифровом пианизме
1
@marius как дополнение: поскольку плагины должны быть специфичны для домена, я думаю, что по крайней мере лучше всего определять несколько плагинов в одном классе, если они являются реализацией одной и той же функции. При переписывании у вас нет этой опции, так как вы всегда меняете целый класс. Так что я думаю, что это было бы одной из причин, по крайней мере, попытаться избежать переписывания
Дэвид Верхолен
@DavidVerholen. Я абсолютно согласен. Но я спрашивал о причинах использования перезаписей вместо плагинов.
Мариус
да, я думаю, что это может быть причиной для использования плагинов, поскольку вы можете определить классы плагинов для конкретных функций, тогда как переписать можно только один раз
David Verholen