¿Por qué los métodos protegidos no pueden ser interceptados?

14

Me preguntaba por qué no es posible crear complementos para protectedmétodos. Hay esta pieza de código en 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;
}

Comprueba si el método es publicantes de permitir que sea interceptado. Se puede cambiar fácilmente mediante la creación de una preferenceen el di.xmlde módulo propio, por supuesto, como este:

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

y reescribiendo _getClassMethodscon el \ReflectionMethod::IS_PUBLICcambio al \ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTEDinterior del método.

Pero me pregunto por qué no es posible interceptar métodos protegidos en la definición de método original. ¿Tiene un impacto importante en el rendimiento, o hay alguna otra razón para eso, como permitir que los módulos de terceros hagan que la lógica de Magento sea demasiado "desordenada"?

Bartosz Górski
fuente

Respuestas:

24

Según los documentos de Magento, no es "posible" usar un complemento en un método protegido.

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

No puede aplicar complementos a:

  • Métodos finales
  • Clases finales
  • Cualquier clase que contenga al menos un método público final.
  • Métodos no públicos.
  • Métodos de clase (como los métodos estáticos)
  • __construir tipos virtuales

Pero su punto es correcto, de acuerdo con la ___callPluginsdefinición en Magento\Framework\Interception\Interceptor, no veo ningún problema al usar métodos protegidos.

Mi primera suposición es que lo limitaron para evitar una alta complejidad de código ya que Magento debería reescribir cualquier método protegido y llamar ___callPluginsa cada uno de ellos ... ralentizará terriblemente en mi humilde opinión.

Pero creo que la verdadera razón es una consistencia lógica: los complementos deberían usarse para cambiar la salida / entrada de los métodos de clase , no para reescribir el comportamiento interno, por lo que solo deberían acceder a los métodos públicos.

Para reescribir un comportamiento interno, debe usar una preferencia. Que tiene sentido.

Phoenix128_RiccardoT
fuente
1
Buena respuesta. También me preguntaba esto, pero desde el punto de vista de OOP / SOLID tiene sentido permitir que solo se intercepten métodos públicos.
Giel Berkers
13

Si no recuerdo mal de una presentación de Anton Krill, dijo que los métodos técnicamente protegidos pueden ser interceptados, pero frustra el propósito de tenerlos "protegidos".
La clase interceptor que se autogenera extiende la clase original para que tenga acceso a los métodos protegidos.
Pero ... Los métodos protegidos no deberían estar disponibles fuera de la clase.
Entonces es más una decisión que una limitación.

Marius
fuente
-4

Es una característica de seguridad de OOPS no específica de magento.

Los métodos públicos, etiquetados por public, están disponibles para cada clase. Los métodos protegidos, etiquetados por protegido están disponibles para subclases y clases amigables, que son clases en el mismo paquete. Los métodos amigables, etiquetados por nada (es decir, por defecto) están disponibles para las clases amigables. Los métodos privados están disponibles solo para la clase misma.

Razones:

1) Los métodos protegidos no pueden acceder en el segundo nivel de herencia.

ejemplo: tomemos un ejemplo de dos clases Clase A y Clase B en el mismo paquete.

La clase B solo puede heredar los métodos protegidos y públicos de la clase A.

Sourav
fuente
44
Protected methods... which are classes in the same package- esto no es verdad. Los métodos protegidos solo están disponibles para las clases disponibles en la misma jerarquía mediante herencia, ya sea que estén en el mismo paquete o no, no hay diferencia. Protected Methods can't access in Inheritence second level.- de nuevo, no es cierto - los métodos protegidos están disponibles en cualquier nivel de herencia, pero no desde fuera del alcance del objeto
Robbie Averill