Warum können geschützte Methoden nicht abgefangen werden?

14

Ich habe mich gefragt, warum es nicht möglich ist, Plugins für protectedMethoden zu erstellen . Es gibt diesen Code in 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;
}

Es wird geprüft, ob die Methode aktiviert ist, publicbevor das Abfangen zugelassen wird. Es kann leicht durch die Schaffung eines geändert werden preferencein der di.xmlvon eigenen Modul, natürlich, wie folgt aus :

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

und das Umschreiben _getClassMethodsmit dem innerhalb der Methode \ReflectionMethod::IS_PUBLICgeänderten \ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED.

Aber ich frage mich, warum es nicht möglich ist, geschützte Methoden in der ursprünglichen Methodendefinition abzufangen. Hat es einen großen Einfluss auf die Leistung oder gibt es einen anderen Grund dafür, zum Beispiel zuzulassen, dass Module von Drittanbietern die Magento-Logik zu "chaotisch" machen?

Bartosz Górski
quelle

Antworten:

24

Laut Magento-Dokumenten ist es nicht "möglich", ein Plugin für eine geschützte Methode zu verwenden.

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

Sie können keine Plugins anwenden auf:

  • Endgültige Methoden
  • Abschlussklassen
  • Jede Klasse, die mindestens eine letzte öffentliche Methode enthält
  • Nicht öffentliche Methoden
  • Klassenmethoden (wie statische Methoden)
  • __konstruieren Sie virtuelle Typen

Aber Ihr Punkt ist richtig, laut ___callPluginsDefinition in Magento\Framework\Interception\Interceptorsehe ich kein Problem mit geschützten Methoden.

Meine erste Vermutung ist, dass sie es begrenzt haben, um eine hohe Codekomplexität zu vermeiden, da Magento jede geschützte Methode und jeden geschützten Aufruf neu schreiben sollte ___callPlugins für jede von ihnen sollte ... es wird IMHO furchtbar verlangsamen.

Aber ich denke, der wahre Grund liegt in einer logischen Übereinstimmung: Plugins sollten verwendet werden, um die Ausgabe / Eingabe der Klassenmethoden zu ändern , nicht, um das interne Verhalten umzuschreiben, sodass sie nur auf öffentliche Methoden zugreifen sollten.

Um ein internes Verhalten umzuschreiben, müssen Sie eine Einstellung verwenden. Es ergibt Sinn.

Phoenix128_RiccardoT
quelle
1
Gute Antwort. Ich habe mich das auch gefragt, aber aus Sicht von OOP / SOLID ist es sinnvoll, nur das Abfangen öffentlicher Methoden zuzulassen.
Giel Berkers
13

Wenn ich mich richtig an eine Präsentation von Anton Krill erinnere, sagte er, dass technisch geschützte Methoden abgefangen werden können, aber dies widerspricht dem Zweck, sie "geschützt" zu haben.
Die automatisch generierte Interceptor-Klasse erweitert die ursprüngliche Klasse, sodass sie Zugriff auf die geschützten Methoden hat.
Aber ... Geschützte Methoden sollten nicht außerhalb der Klasse verfügbar sein.
Es ist also eher eine Entscheidung als eine Einschränkung.

Marius
quelle
-4

Es ist keine magento-spezifische OOPS-Sicherheitsfunktion.

Öffentliche Methoden, die mit public gekennzeichnet sind, stehen jeder Klasse zur Verfügung. Geschützte Methoden, die mit protected gekennzeichnet sind, stehen Unterklassen und Anzeigenklassen zur Verfügung, die Klassen im selben Paket sind. Friendly-Methoden, die mit nothing (dh default) gekennzeichnet sind, stehen Friendly-Klassen zur Verfügung. Private Methoden stehen nur der Klasse selbst zur Verfügung.

Gründe dafür:

1) Geschützte Methoden können nicht auf die zweite Ebene von Inheritence zugreifen.

Beispiel: Nehmen wir als Beispiel zwei Klassen der Klassen A und B in demselben Paket.

Klasse B kann nur vererbungsgeschützt sein sowie öffentliche Methoden der Klasse A.

Sourav
quelle
4
Protected methods... which are classes in the same package- das ist nicht wahr. Geschützte Methoden sind nur für Klassen verfügbar, die in derselben Hierarchie über eine Vererbung verfügbar sind - unabhängig davon, ob sie sich im selben Paket befinden oder nicht. Protected Methods can't access in Inheritence second level.- Auch hier sind auf jeder Vererbungsebene nicht wahrheitsgeschützte Methoden verfügbar, nur nicht außerhalb des Objektbereichs
Robbie Averill