Les getters magiques sur Varien_Object
(M1) et DataObject
(M2) sont une pratique courante, mais avec Magento 2, il ne convient pas de l'utiliser.
Bien:
- facile à lire / écrire
Mal
- Cela pose des problèmes lors de l'utilisation de chiffres dans les clés (voir: Magento 2: manière différente d'obtenir le champ d'une collection ou d' obtenir un attribut de produit personnalisé à l'aide de la camel case )
- les outils d'analyse de code se plaignent de méthodes inexistantes
Question
Avec Magento 2, nous avons deux nouvelles méthodes:
getDataByKey($key)
getDataByPath($path)
Y a-t-il une bonne raison d'utiliser encore getData($key)
ou des getters magiques?
Éditer:
@Vinai merci. Je n'ai pas mentionné la @method
méthode, car mon approche était assez différente.
Cela n'aide que l'IDE, mais n'a aucun impact sur d'autres choses.
Il existe plusieurs PR fusionnés sur lesquels sont des «micro-optimisations», comme le transtypage en (int)
lieu et place intval()
ou la taille des tableaux en dehors des boucles (même pour les petits tableaux).
D'un autre côté, il y a
des getters magiques, qui ont des "frais généraux" comme Marius l'a décrit ....
strtolower(trim(preg_replace('/([A-Z]|[0-9]+)/', "_$1", $name), '_'));
getData($key)
les mehtods doivent également effectuer 2 à 3 contrôles supplémentaires ...if ('' === $key) {
if (strpos($key, '/')) {
if ($index !== null) {
Pour votre propre code, vous êtes totalement d'accord pour préférer de vraies méthodes, mais dans les mêmes cas ce n'est pas possible ... par exemple, vous avez créé un événement personnalisé ...
$value = $observer->getVar_1();
$value = $observer->getData('var_1');
$value = $observer->getDataByKey('var_1');
Utiliser le 3e avec /** @var some $value */
me semble le mieux. (?)
Réponses:
La question ci-dessus concerne l'utilisation de méthodes magiques contre
getDataByKey
ougetDataByPath
. Je pense qu'il y a aussi une troisième option, qui met en œuvre de vraies méthodes getter et setter.Les
getData*
méthodes ont toutes l'inconvénient de devoir être annotées pour que l'inférence de type fonctionne.Habituellement, cela se fait avec une
/* @var string $foo */
annotation au-dessus de l'getData*
appel.C'est un peu malodorant, car le type des données doit être déclaré dans la classe qui contient les données, pas la classe qui appelle
getData*
.La raison en est que si les données changent, la classe est la plus susceptible d'être mise à jour, pas tous
getData*
les sites d'appel.C'est pourquoi je pense que les méthodes réelles augmentent la maintenabilité par rapport à l'utilisation d'
getData*
accesseurs.Je pense donc que cela se résume à un compromis entre la maintenabilité et une implémentation plus rapide (moins de code à écrire).
Heureusement, de nos jours, les IDE sont vraiment bons pour créer les implémentations getter et setter pour nous, donc cet argument ne s'applique plus vraiment.
Un autre argument contre les getters et setters magiques qui manque dans la question ci-dessus est qu'il n'est pas possible de créer des plugins pour eux.
La seule autre valeur que je pense pouvoir ajouter au sujet est d'essayer de collecter les raisons d'utiliser ou de ne pas utiliser d'
@method
annotations, si la mise en œuvre de méthodes réelles est hors de question pour une raison quelconque.Avantages
@method
annotation est un peu moins de code à écrire que l'implémentation d'un vrai getter et setter. Cela est à peine vrai de nos jours car les IDE sont bons pour générer des méthodes d'accesseur, donc ce n'est plus un réel avantage.Les inconvénients
@method
existe à la fois une annotation et une méthode réelle du même nom, la signature du type d'annotation remplace la méthode réelle lors de l'analyse de code statique, ce qui est l'opposé de ce que fait l'interpréteur PHP. Encore une fois, cela peut facilement conduire à des bugs subtils.Pour les raisons ci-dessus, personnellement, je n'utilise pas d'
@method
annotations si je peux les éviter.Pour le code qui est destiné à vivre longtemps, j'implémente de vraies méthodes getter et setter. Le gain de maintenabilité vaut la peine de déclencher l'IDE pour les générer.
Pour du code plus expérimental lors d'un pic, ou pour un simple détail d'implémentation d'un module, j'utilise aussi des
getData*
méthodes, car je suis paresseux.la source
Oui, il sent mauvais, mais peut (et devrait?) Être évité. Je pense que c'est un code très courant et souvent suggéré:
Le problème est que vous devinez simplement que la valeur de retour est de type
Foo
avec unegetId()
méthode appelable .Pour la maintenabilité, pourquoi ne pas assumer le type de variable et ajouter un
InvalidArgumentException
?Cela corrige également l'analyse de code statique dans le cas qui
$model->getProduct()
a différents types de retour - commeFoo|false
. Dans le premier cas, il se plaindrait d'appelerdoSomething()
possiblefalse
.la source