Perché i metodi protetti non possono essere intercettati?


14

Mi chiedevo perché non fosse possibile creare plugin per protectedmetodi. C'è questo pezzo di codice nel 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;
}

Verifica se il metodo è publicprima di consentirne l'intercettazione. Può essere facilmente modificato creando un preferencein nel di.xmlproprio modulo, ovviamente, in questo modo:

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

e riscrivendo il _getClassMethodscon il \ReflectionMethod::IS_PUBLICmodificato \ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTEDall'interno del metodo.

Ma mi chiedo perché non sia possibile intercettare metodi protetti nella definizione del metodo originale? Ha un impatto notevole sulle prestazioni, o c'è qualche altra ragione per questo, come consentire ai moduli di terze parti di rendere la logica di Magento troppo "disordinata"?

Risposte:


24

Secondo i documenti di Magento non è "possibile" utilizzare un plugin su un metodo protetto.

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

Non puoi applicare plugin a:

  • Metodi finali
  • Classi finali
  • Qualsiasi classe che contiene almeno un metodo pubblico finale
  • Metodi non pubblici
  • Metodi di classe (come metodi statici)
  • __costruire i tipi virtuali

Ma il tuo punto è corretto, secondo la ___callPluginsdefinizione in Magento\Framework\Interception\Interceptor, non vedo alcun problema usando i metodi protetti.

La mia prima ipotesi è che l'hanno limitato per evitare un'elevata complessità del codice poiché Magento dovrebbe riscrivere qualsiasi metodo protetto e chiamare ___callPluginsper ciascuno di essi ... rallenterà terribilmente IMHO.

Ma penso che la vera ragione sia per una coerenza logica: i plugin dovrebbero essere usati per cambiare l'output / input dei metodi di classe , non per riscrivere il comportamento interno, quindi dovrebbero accedere solo a metodi pubblici.

Per riscrivere un comportamento interno devi usare una preferenza. Ha senso.


1
Buona risposta. Me lo stavo chiedendo anche io, ma dal punto di vista OOP / SOLID ha senso consentire l'intercettazione dei soli metodi pubblici.
Giel Berkers,

13

Se ricordo bene da una presentazione di Anton Krill, ha detto che i metodi tecnicamente protetti possono essere intercettati, ma vanifica lo scopo di averli "protetti".
La classe interceptor che viene generata automaticamente estende la classe originale in modo che abbia accesso ai metodi protetti.
Ma ... I metodi protetti non dovrebbero essere disponibili al di fuori della classe.
Quindi è più una decisione che una limitazione.


-4

È la funzionalità di sicurezza OOPS non specifica per magento.

I metodi pubblici, etichettati dal pubblico sono disponibili per ogni classe. I metodi protetti, etichettati come protetti sono disponibili per le sottoclassi e le classi amichevoli, che sono classi nello stesso pacchetto. I metodi amichevoli, etichettati dal nulla (cioè predefiniti) sono disponibili per le classi amichevoli. I metodi privati ​​sono disponibili solo per la classe stessa.

Motivi:

1) I metodi protetti non possono accedere al secondo livello di ereditarietà.

esempio: prendiamo un esempio di due classi Classe A e Classe B nello stesso pacchetto.

La classe B può proteggere solo l'ereditarietà nonché i metodi pubblici di classe A.


4
Protected methods... which are classes in the same package- questo non è vero. I metodi protetti sono disponibili solo per le classi disponibili nella stessa gerarchia tramite ereditarietà, indipendentemente dal fatto che siano nello stesso pacchetto o meno. Protected Methods can't access in Inheritence second level.- di nuovo, non è vero - i metodi protetti sono disponibili a qualsiasi livello di ereditarietà, non solo al di fuori dell'ambito dell'oggetto
Robbie Averill
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.