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"?

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.


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.


-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.


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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.