Magic Getter auf Varien_Object
(M1) und DataObject
(M2) sind gängige Praxis, aber mit Magento 2 fühlt es sich falsch an, es zu verwenden.
Gut:
- leicht zu lesen / schreiben
Schlecht
- Dies führt zu Problemen bei der Verwendung von Ziffern in Schlüsseln (siehe: Magento 2: Anderer Weg zum Abrufen eines Felds einer Sammlung oder Attribut "Benutzerdefiniertes Produkt abrufen" mit Kamelkasten ).
- Tools zur Code-Analyse beschweren sich über nicht vorhandene Methoden
Frage
Mit Magento 2 haben wir zwei neue Methoden:
getDataByKey($key)
getDataByPath($path)
Gibt es noch einen guten Grund für den Einsatz getData($key)
oder irgendwelche Zauberkünstler?
Bearbeiten:
@ Vinai danke. Ich habe die @method
Methode nicht erwähnt , weil mein Ansatz ganz anders war.
Es hilft nur der IDE, hat aber keinen Einfluss auf andere Dinge.
Es gibt mehrere mergedf PRs auf, die „Mikro-Optimierungen“ wie Gießen (int)
statt intval()
oder Array - Größe außerhalb Schleifen (auch für kleine Arrays) erhalten.
Auf der anderen Seite gibt es
magische Getter, die etwas "Overhead" haben, wie Marius es beschrieben hat ....
strtolower(trim(preg_replace('/([A-Z]|[0-9]+)/', "_$1", $name), '_'));
getData($key)
Mehtods müssen auch 2-3 zusätzliche Prüfungen ...if ('' === $key) {
if (strpos($key, '/')) {
if ($index !== null) {
Für eigenen Code ist es völlig einverstanden, echte Methoden zu bevorzugen, aber in den gleichen Fällen ist dies möglicherweise nicht der Fall ... Sie haben z. B. ein benutzerdefiniertes Ereignis erstellt ...
$value = $observer->getVar_1();
$value = $observer->getData('var_1');
$value = $observer->getDataByKey('var_1');
3. mit /** @var some $value */
scheinen mir am besten. (?)
Antworten:
Bei der obigen Frage geht es um die Verwendung magischer Methoden im Vergleich zu
getDataByKey
odergetDataByPath
. Ich denke, es gibt auch eine dritte Option, nämlich die Implementierung echter Get- und Setter-Methoden.Die
getData*
Methoden haben alle den Nachteil, dass sie mit Anmerkungen versehen werden müssen, damit die Typinferenz funktioniert.In der Regel erfolgt dies mit einer
/* @var string $foo */
Anmerkung über demgetData*
Aufruf.Dies ist etwas stinkend, da der Datentyp in der Klasse deklariert werden sollte, die die Daten enthält, nicht in der Klasse, die aufruft
getData*
.Der Grund dafür ist, dass bei einer Änderung der Daten die Aktualisierung der Klasse am wahrscheinlichsten ist und nicht aller
getData*
Aufrufsites.Deshalb glaube ich, dass echte Methoden die Wartbarkeit im Vergleich zur Verwendung von
getData*
Accessoren verbessern.Ich denke, es läuft auf einen Kompromiss zwischen Wartbarkeit und schnellerer Implementierung hinaus (weniger Code zum Schreiben).
Glücklicherweise sind IDEs heutzutage wirklich gut darin, die Get- und Setter-Implementierungen für uns zu erstellen, sodass dieses Argument nicht mehr wirklich zutrifft.
Ein weiteres Argument gegen Magic Getter und Setter, das in der obigen Frage fehlt, ist, dass es nicht möglich ist, Plugins für sie zu erstellen.
Der einzige andere Wert, den ich dem Thema hinzufügen kann, ist der Versuch, die Gründe für die Verwendung oder Nichtverwendung von
@method
Anmerkungen zu sammeln , wenn die Implementierung realer Methoden aus irgendeinem Grund nicht in Frage kommt.Vorteile
@method
Annotation ist etwas weniger zu schreibender Code als die Implementierung eines echten Get- und Setters. Heutzutage ist dies jedoch kaum mehr der Fall, da IDEs gut darin sind, Zugriffsmethoden zu generieren. Dies ist also kein wirklicher Vorteil mehr.Nachteile
@method
Annotation als auch eine reale Methode mit demselben Namen vorhanden sind, überschreibt die Signatur des Annotationstyps die reale Methode bei der statischen Code-Analyse. Dies ist das Gegenteil von dem, was der PHP-Interpreter tut. Dies kann wiederum leicht zu subtilen Fehlern führen.Aus den oben genannten Gründen verwende ich persönlich keine
@method
Anmerkungen, wenn ich sie vermeiden kann.Für Code, der lange leben soll, implementiere ich echte Getter- und Setter-Methoden. Der Gewinn an Wartbarkeit ist die Anstrengung wert, die IDE auszulösen, um sie zu generieren.
Für mehr experimentellen Code während eines Spikes oder für ein einfaches Implementierungsdetail eines Moduls verwende ich auch
getData*
Methoden, weil ich faul bin.quelle
Ja, es riecht, aber kann (und sollte?) Vermieden werden. Ich denke, das ist sehr allgemeiner Code und wird oft vorgeschlagen:
Das Problem ist, dass Sie nur vermuten, dass der Rückgabewert vom Typ
Foo
mit einer aufrufbarengetId()
Methode ist.Nehmen Sie aus Gründen der Wartbarkeit einen Variablentyp an und fügen Sie einen hinzu
InvalidArgumentException
.Dies behebt auch die statische Code-Analyse für den Fall, dass
$model->getProduct()
unterschiedliche Rückgabetypen vorliegenFoo|false
. Im ersten Fall würde er sich über einendoSomething()
eventuellen Rückruf beschwerenfalse
.quelle