Por que métodos protegidos não podem ser interceptados?

14

Fiquei me perguntando por que não é possível criar plugins para protectedmétodos. Há esse pedaço de código no 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;
}

Ele verifica se o método está publicantes de permitir sua interceptação. Ele pode ser facilmente alterado através da criação de um preferenceno di.xmlde próprio módulo, é claro, como este:

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

e reescrevendo o _getClassMethodscom o \ReflectionMethod::IS_PUBLICalterado para \ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTEDdentro do método.

Mas eu me pergunto por que não é possível interceptar métodos protegidos na definição do método original? Isso tem um grande impacto no desempenho ou há outra razão para isso, como permitir que módulos de terceiros tornem a lógica do Magento muito "bagunçada"?

Bartosz Górski
fonte

Respostas:

24

De acordo com a documentação do Magento, não é "possível" usar um plug-in em um método protegido.

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

Você não pode aplicar plugins para:

  • Métodos finais
  • Aulas finais
  • Qualquer classe que contenha pelo menos um método público final
  • Métodos não públicos
  • Métodos de classe (como métodos estáticos)
  • __construir tipos virtuais

Mas seu argumento está correto, de acordo com a ___callPluginsdefinição em Magento\Framework\Interception\Interceptor, não vejo nenhum problema ao usar métodos protegidos.

Meu primeiro palpite é que eles o limitaram para evitar uma alta complexidade de código, uma vez que o Magento deveria reescrever qualquer método protegido e chamar ___callPluginscada um deles ... isso desaceleraria terrivelmente o IMHO.

Mas acho que a verdadeira razão é uma consistência lógica: os plug - ins devem ser usados ​​para alterar a saída / entrada dos métodos de classe , não para reescrever o comportamento interno, portanto, eles devem acessar apenas métodos públicos.

Para reescrever um comportamento interno, você deve usar uma preferência. Faz sentido.

Phoenix128_RiccardoT
fonte
1
Boa resposta. Eu também estava pensando isso, mas do ponto de vista de OOP / SOLID, faz sentido permitir apenas que métodos públicos sejam interceptados.
Giel Berkers
13

Se bem me lembro de uma apresentação de Anton Krill, ele disse que métodos tecnicamente protegidos podem ser interceptados, mas isso anula o propósito de tê-los "protegidos".
A classe interceptora gerada automaticamente estende a classe original para que ela tenha acesso aos métodos protegidos.
Mas ... Métodos protegidos não devem estar disponíveis fora da classe.
Portanto, é mais uma decisão do que uma limitação.

Marius
fonte
-4

É um recurso de segurança OOPS não específico do magento.

Métodos públicos, rotulados por público, estão disponíveis para todas as classes. Os métodos protegidos, rotulados por protected, estão disponíveis para subclasses e classes amigáveis, que são classes no mesmo pacote. Métodos amigáveis, rotulados por nada (ou seja, padrão), estão disponíveis para classes amigáveis. Métodos particulares estão disponíveis apenas para a própria classe.

Razões:

1) Métodos protegidos não podem acessar no segundo nível de herança.

exemplo: Vamos dar um exemplo de duas classes Classe A e Classe B no mesmo pacote.

A classe B só pode proteger métodos de herança e métodos públicos da classe A.

Sourav
fonte
4
Protected methods... which are classes in the same package- isso não é verdade. Os métodos protegidos estão disponíveis apenas para classes disponíveis na mesma hierarquia por herança - se eles estão no mesmo pacote ou não, não faz diferença. Protected Methods can't access in Inheritence second level.- mais uma vez, não é verdade - protegido métodos estão disponíveis em qualquer nível de herança, não apenas de fora do escopo do objeto
Robbie Averill