Чому захищені методи не можуть бути перехоплені?


14

Мені було цікаво, чому неможливо створити плагіни для protectedметодів. Цей код у Magento\Framework\Interception\Code\Generator\Interceptor:

protected function _getClassMethods()
{
    $methods = [$this->_getDefaultConstructorDefinition()];

    $reflectionClass = new \ReflectionClass($this->getSourceClassName());
    $publicMethods = $reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC);
    foreach ($publicMethods as $method) {
        if ($this->isInterceptedMethod($method)) {
            $methods[] = $this->_getMethodInfo($method);
        }
    }
    return $methods;
}

Він перевіряє, чи є метод, publicперш ніж дозволяти йому перехоплюватися. Це може бути легко змінена шляхом створення preferenceв di.xmlвласному модулі, звичайно ж , як це:

<?xml version="1.0"?>
<config>
    <preference for="Magento\Framework\Interception\Code\Generator\Interceptor" type="MyVendor\MyModule\Model\MyInterceptorModel" />
</config>

і переписавши _getClassMethodsз \ReflectionMethod::IS_PUBLICзмінено на \ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTEDвнутрішню частини методи.

Але мені цікаво, чому неможливо перехопити захищені методи в початковому визначенні методу? Чи має це великий вплив на продуктивність, чи є якась інша причина для цього, наприклад, дозволяючи стороннім модулям зробити логіку Magento занадто "брудною"?

Відповіді:


24

Згідно з документами Magento, не можна "використовувати" плагін захищеним методом.

( http://devdocs.magento.com/guides/v2.0/extension-dev-guide/plugins.html )

Не можна застосовувати плагіни до:

  • Заключні методи
  • Підсумкові заняття
  • Будь-який клас, який містить хоча б один остаточний публічний метод
  • Непублічні методи
  • Методи класу (наприклад, статичні методи)
  • __конструюйте віртуальні типи

Але ваша думка правильна, згідно з ___callPluginsвизначенням в Magento\Framework\Interception\Interceptor, я не бачу жодної проблеми у використанні захищених методів.

Перший мій припущення полягає в тому, що вони обмежили його, щоб уникнути високої складності коду, оскільки Magento повинен переписати будь-який захищений метод і викликати ___callPluginsкожен з них ... це страшенно сповільнить IMHO.

Але я думаю, що справжня причина полягає в логічній постійності: плагіни повинні використовуватися для зміни методів класу виведення / введення , а не для переписування внутрішньої поведінки, тому вони повинні мати доступ лише до публічних методів.

Щоб переписати внутрішню поведінку, ви повинні скористатись уподобанням. Це має сенс.


1
Гарна відповідь. Мені це теж було цікаво, але з точки зору OOP / SOLID є сенс дозволити перехоплювати лише публічні методи.
Giel Berkers

13

Якщо я добре пам'ятаю з презентації Антона Крила, він сказав, що технічно захищені методи можуть бути перехоплені, але це перемагає мету їх "захищати".
Клас перехоплення, який автоматично генерується, розширює початковий клас, щоб він мав доступ до захищених методів.
Але ... Захищені методи не повинні бути доступні поза класом.
Тож це скоріше рішення, ніж обмеження.


-4

Це функція безпеки OOPS, не специфічна для магенто.

Публічні методи, позначені громадськістю, доступні для кожного класу. Захищені методи, позначені захищеними, доступні для підкласів та дружніх класів, які є класами в одному пакеті. Дружні методи, позначені нічим (тобто за замовчуванням), доступні для дружніх занять. Приватні методи доступні лише для самого класу.

Причини:

1) Захищені методи не можуть отримати доступ у спадщині другого рівня.

приклад: Давайте візьмемо для прикладу два класи класу A та класу B в одному пакеті.

Клас B може мати лише спадкові захищені, а також публічні методи класу A.


4
Protected methods... which are classes in the same package- це не правда. Захищені методи доступні лише для класів, доступних в одній ієрархії через успадкування - незалежно від того, чи є вони в одному пакеті, чи не має ніякої різниці. Protected Methods can't access in Inheritence second level.- знову ж таки, неправда - захищені методи доступні на будь-якому рівні спадкування, тільки не з-за меж об'єкта
Роббі Аверилл
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.