Les traits ont été l'un des plus gros ajouts pour PHP 5.4. Je connais la syntaxe et comprends l'idée derrière les traits, comme la réutilisation horizontale du code pour des choses courantes comme la journalisation, la sécurité, la mise en cache, etc.
Cependant, je ne sais toujours pas comment j'utiliserais des traits dans mes projets.
Existe-t-il des projets open source qui utilisent déjà des traits? Y a-t-il de bons articles / lectures sur la façon de structurer des architectures à l'aide de traits?
Réponses:
Mon opinion personnelle est qu'il y a en fait très peu d'applications pour les traits lors de l'écriture de code propre.
Au lieu d'utiliser des traits pour pirater du code dans une classe, il est préférable de passer les dépendances via le constructeur ou via des setters:
La principale raison pour laquelle je trouve cela meilleur que l'utilisation de traits est que votre code est beaucoup plus flexible en supprimant le couplage dur à un trait. Par exemple, vous pouvez simplement passer une classe d'enregistrement différente maintenant. Cela rend votre code réutilisable et testable.
la source
Je suppose qu'il faudrait se pencher sur les langues qui ont des traits depuis un certain temps maintenant pour apprendre les bonnes / meilleures pratiques acceptées. Mon opinion actuelle sur Trait est que vous ne devriez les utiliser que pour du code que vous auriez à dupliquer dans d'autres classes partageant les mêmes fonctionnalités.
Exemple de trait Logger:
Et puis tu fais ( démo )
Je suppose que la chose importante à considérer lors de l'utilisation de traits est qu'ils ne sont en réalité que des morceaux de code qui sont copiés dans la classe. Cela peut facilement conduire à des conflits, par exemple, lorsque vous essayez de modifier la visibilité des méthodes, par exemple
Ce qui précède entraînera une erreur ( démo ). De même, toutes les méthodes déclarées dans le trait qui sont également déjà déclarées dans la classe using ne seront pas copiées dans la classe, par exemple
imprimera 2 ( démo ). Ce sont des choses que vous voudrez éviter car elles rendent les erreurs difficiles à trouver. Vous voudrez également éviter de mettre des choses dans des traits qui opèrent sur des propriétés ou des méthodes de la classe qui l'utilise, par exemple
fonctionne ( démo ) mais maintenant le trait est intimement lié à A et toute l'idée de réutilisation horizontale est perdue.
Lorsque vous suivez le principe de séparation des interfaces, vous aurez de nombreuses petites classes et interfaces. Cela fait de Traits un candidat idéal pour les choses que vous avez mentionnées, par exemple les préoccupations transversales , mais pas pour composer des objets (dans un sens structuré). Dans notre exemple Logger ci-dessus, le trait est complètement isolé. Il n'a pas de dépendances sur les classes concrètes.
Nous pourrions utiliser l' agrégation / composition (comme indiqué ailleurs sur cette page) pour obtenir la même classe résultante, mais l'inconvénient d'utiliser l'agrégation / composition est que nous devrons ajouter manuellement les méthodes proxy / délégant à chaque classe, alors cela devrait être en mesure de se connecter. Les traits résolvent bien ce problème en me permettant de garder le passe-partout au même endroit et de l'appliquer de manière sélective si nécessaire.
Remarque: étant donné que les traits sont un nouveau concept en PHP, toutes les opinions exprimées ci-dessus sont susceptibles de changer. Je n'ai pas encore eu beaucoup de temps pour évaluer moi-même le concept. Mais j'espère que c'est assez bon pour vous donner quelque chose à penser.
la source
:) Je n'aime pas théoriser et débattre de ce qu'il faut faire avec quelque chose. Dans ce cas, les traits. Je vais vous montrer à quoi je trouve utile les traits et vous pouvez soit en tirer des leçons, soit les ignorer.
Traits - ils sont parfaits pour appliquer des stratégies . Les modèles de conception de stratégie, en bref, sont utiles lorsque vous souhaitez que les mêmes données soient traitées (filtrées, triées, etc.) différemment.
Par exemple, vous avez une liste de produits que vous souhaitez filtrer en fonction de certains critères (marques, spécifications, peu importe), ou triés par différents moyens (prix, étiquette, peu importe). Vous pouvez créer un trait de tri qui contient différentes fonctions pour différents types de tri (numérique, chaîne, date, etc.). Vous pouvez ensuite utiliser cette caractéristique non seulement dans votre classe de produit (comme indiqué dans l'exemple), mais également dans d'autres classes qui nécessitent des stratégies similaires (pour appliquer un tri numérique à certaines données, etc.).
Essayez-le:
En guise de conclusion, je pense à des traits comme les accessoires (que je peux utiliser pour modifier mes données). Des méthodes et des propriétés similaires qui peuvent être supprimées de mes classes et mises en un seul endroit, pour une maintenance facile, un code plus court et plus propre.
la source
strategies
.Je suis enthousiasmé par Traits car ils résolvent un problème courant lors du développement d'extensions pour la plate-forme de commerce électronique Magento. Le problème se produit lorsque les extensions ajoutent des fonctionnalités à une classe principale (comme par exemple le modèle User) en l'étendant. Ceci est fait en pointant l'autochargeur Zend (via un fichier de configuration XML) pour utiliser le modèle User de l'extension, et faire étendre le nouveau modèle du modèle de base. ( exemple ) Mais que se passe-t-il si deux extensions remplacent le même modèle? Vous obtenez une "condition de concurrence" et une seule est chargée.
La solution à l'heure actuelle consiste à modifier les extensions afin que l'une étende la classe de remplacement de modèle de l'autre dans une chaîne, puis à définir la configuration d'extension pour les charger dans le bon ordre afin que la chaîne d'héritage fonctionne.
Ce système provoque fréquemment des erreurs et lors de l'installation de nouvelles extensions, il est nécessaire de vérifier les conflits et de modifier les extensions. C'est pénible et interrompt le processus de mise à niveau.
Je pense que l'utilisation de Traits serait un bon moyen d'accomplir la même chose sans cette «condition de course» ennuyeuse du modèle. Certes, il pourrait encore y avoir des conflits si plusieurs Traits implémentaient des méthodes avec les mêmes noms, mais j'imagine que quelque chose comme une simple convention d'espace de noms pourrait résoudre cela pour la plupart.
TL; DR Je pense que Traits pourrait être utile pour créer des extensions / modules / plugins pour de gros progiciels PHP comme Magento.
la source
Vous pourriez avoir un trait pour un objet en lecture seule comme celui-ci:
Vous pouvez détecter si ce trait est utilisé et déterminer si vous devez ou non écrire cet objet dans une base de données, un fichier, etc.
la source
use
ce trait alorsif($this -> getReadonly($value))
; mais cela générerait une erreur si vous ne faisiez pasuse
ce trait. Cet exemple est donc défectueux.