Utiliser PHP CodeSniffer avec WordPress Comprendre les odeurs de code

Souvent, la façon dont nous écrivons du code dépend de la façon dont nous avons commencé à programmer.

Par exemple, si une personne a fait des études en informatique, elle est susceptible de connaître une série de principes qui l’empêcheront d’écrire un code de mauvaise qualité. Ce n'est pas une règle, bien sûr, mais une observation. 

De même, ceux qui se lancent seuls dans la programmation, en dehors d'un cadre formel, finissent souvent par enseigner eux-mêmes et par apprendre à partir d'une variété de ressources différentes. Parfois, cela peut causer des problèmes avec le type de code écrit.

Pour être tout à fait clair: je ne dis pas qu'une formation formelle en informatique l'emporte sur quelqu'un qui enseigne soi-même, ni l'inverse. Certains programmeurs fantastiques sont ceux qui sont éduqués; les autres sont des autodidactes. Mais ce qu’ils ont tous deux en commun, c’est qu’ils ne sont pas dispensés d’écrire des odeurs de code de temps en temps..

Dans cet article, nous allons passer en revue les odeurs de code. Nous allons examiner ce qu’ils sont, à quoi ils ressemblent et comment ils se manifestent souvent dans notre travail. Nous allons utiliser PHP pour nos exemples.

Dans la deuxième partie de cette série, nous allons voir comment éviter d'écrire des odeurs de code. Plus précisément, nous utiliserons PHP, quelques outils et WordPress comme environnement de prédilection..

Mais d'abord, commençons par une introduction au code qui sent.

Quelles sont les odeurs de code?

Selon le type de développeur que vous demandez, vous obtiendrez probablement une variante de la définition suivante:

L'odeur de code, également appelée mauvaise odeur, dans le code de programmation informatique, fait référence à tout symptôme du code source d'un programme pouvant indiquer un problème plus grave.. 

Cette définition est directement de Wikipedia. Ce n'est pas mauvais, mais ce n'est pas mon opinion préférée sur le sujet. Au lieu de cela, ma définition préférée vient d'un programmeur prolifique et populaire appelé Martin Fowler. Vous pouvez lire son article complet sur le sujet des odeurs de code dans cet article, mais je l'ai résumé aux points suivants:

  1. "Une longue méthode en est un bon exemple: il suffit de regarder le code et les contractions de mon nez si je vois plus d'une douzaine de lignes de Java."
  2. "Les odeurs ne sont pas intrinsèquement mauvaises - elles sont souvent un indicateur d'un problème plutôt que le problème elles-mêmes."
  3. "Les classes de données (avec toutes les données et aucun comportement) sont de bons exemples."

Si vous n'avez pas lu l'article, il termine avec ceci:

Une des bonnes choses à propos des odeurs est qu'il est facile pour les personnes inexpérimentées de les repérer, même si elles n'en savent pas assez pour évaluer s'il existe un problème réel ou pour les corriger.. 

Et je pense que c'est une déclaration fantastique car cela signifie que ce sujet est parfaitement positionné pour ceux qui sont programmeurs mais ne savent pas par où commencer pour identifier et traiter les odeurs de code..

En bref, l'expérience ne joue pas un grand rôle à cet égard. Bien sûr, ceux qui sont plus expérimentés sont susceptibles d'identifier plus facilement les odeurs (car ils en ont vu plus), mais les développeurs moins expérimentés devraient pouvoir les identifier..

Avez-vous des exemples?

Bien sûr, quand il s'agit d'un sujet comme le code qui sent, il est souvent plus facile d'en parler à un niveau abstrait que de faire quelque chose à leur sujet. Mais ce n'est ni pratique, ni applicable à notre travail quotidien.

Cela dit, pourquoi ne pas jeter un coup d'œil à un exemple de code odorant? Nous examinerons les raisons pour lesquelles ils posent problème, puis proposerons une solution permettant de supprimer les odeurs en refacturant le code..

Exemple 1: Effacer les conventions de dénomination

L'une des odeurs de code les plus faciles à détecter est lorsqu'un programmeur a choisi d'utiliser des noms de variables peu clairs. Autrement dit, dans le contexte du code, il n’est pas clair de savoir ce qu’une variable donnée est censée représenter.

Bien sûr, il y a des moments où cela est acceptable (comme utiliser un je dans un pour boucle). Mais dans une méthode plus longue, ce n'est pas tout à fait la même chose que pour boucle). 

Par exemple:

Avec suffisamment de temps, nous serions probablement en mesure de comprendre ce que cela fait. Tout d'abord, c'est une méthode relativement simple. Deuxièmement, nous serions en mesure de lire les variables, les blocs et revenir valeur pour avoir une meilleure idée de ce qui se passe.

Mais si nous cherchons à écrire un code propre qui soit plus facile à comprendre lorsque nous nous y référons ou qu'un autre programmeur l'utilise, il est toujours utile d'utiliser des conventions de dénomination claires. Et le code ci-dessus n'utilise pas de conventions de dénomination claires.

Au lieu de cela, modifions-le pour qu'il ressemble à ceci:

Beaucoup plus facile à comprendre, n'est-ce pas?

Notez que l'algorithme lui-même n'a pas changé, mais le nom de la fonction et les noms de variables ont changé. Cela a fait cette beaucoup de différence dans la lecture de ce code. Si on vous demande ce que ce code est censé faire, nous pouvons facilement dire quelque chose comme:

Renvoie un tableau d'éléments marqué comme vrai à partir d'un tableau d'éléments prédéfini..

Autant que possible, évitez d'utiliser des noms de variables génériques et utilisez l'option la plus claire pour vous et vos pairs..

Exemple 2: Restez au sec

En programmation, vous auriez du mal à trouver un développeur qui n'ait pas entendu parler de KISS ou DRY (vous savez, "ne vous répétez pas"). Malgré cela, nous avons souvent faire répète nous. 

Ceci est révélateur du fait que la tentative d'adhérer aux principes DRY atterrit différemment avec différents types de programmeurs. Et c'est bon! Il n'y a pas qu'un seul moyen de démontrer comment adhérer à ce principe.

Mais comme il existe de nombreuses façons de le faire, nous pouvons donner un exemple de ce à quoi cela ne devrait pas ressembler et à quoi cela devrait ressembler..

Supposons, aux fins de l'exemple suivant, que nous avons une fonction appelée save_post et qu'elle accepte deux arguments: un ID de publication et une chaîne représentant le titre de la publication. Une odeur de code ressemblerait à ceci:

Mais pourquoi devrions-nous taper manuellement un appel à save_post trois fois? À la place, configurons un tableau associatif, parcourons-le, puis appelons la méthode une fois par itération..

 'Hello World!', 2 => 'Au revoir World!', 3 => 'Qu'est-ce que ce nouveau monde?',]; foreach ($ post as $ post_id => $ post_title) save_post ($ post_id, $ post_title); 

Bien que l’appel de la méthode une fois soit agréable, la méthode pourrait être encore plus flexible en lui faisant accepter le tableau de posts comme argument et en laissant le pour chaque boucle intacte, bien que ce ne soit pas vraiment le but de cet exemple.

Si vous appelez plusieurs fois la même méthode dans une fonction mais avec des paramètres différents, vous pouvez avoir une odeur de code. Et si vous le faites, cherchez des moyens de le refactoriser de sorte que vous n’appeliez la méthode qu’une seule fois.. 

Après tout, vous ne voulez pas vous répéter.

Exemple 3: longues listes de paramètres

L’une des choses les plus communes que nous continuons à voir dans la programmation, peu importe le langage, est quand une fonction accepte un grand nombre de paramètres. 

Différents programmeurs auront des opinions sur le nombre idéal de paramètres qu'une fonction devrait accepter, mais j'ai tendance à penser que trois (donne ou prend deux, peut-être) est un bon nombre.

Tout d’abord, examinons à quoi ressemblerait une fonction avec une longue liste de paramètres. Il n'y a probablement pas de surprises dans le code suivant, et vous pouvez avoir affaire à quelque chose de semblable dans l'un de vos projets en cours:

Notez que dans l'exemple ci-dessus, l'implémentation de la fonction ne nous concerne pas. Au lieu de cela, nous sommes préoccupés par le nombre de paramètres requis. Cela fait beaucoup d'informations à envoyer, et l'appel de la méthode sera fait cette beaucoup plus laid aussi.

Cela n'aborde même pas le sujet de la vérification et de la validation. Mais je m'éloigne de ça.

Comment celui-ci pourrait-il être nettoyé? Personnellement, je suis un fan de la création de classes pour représenter des collections d’informations comme celle-ci. Pour cet exemple particulier, nous pourrions avoir une classe qui présente les informations de contact d'une personne. En outre, cette personne pourrait être associée à un numéro de carte de crédit. 

Les détails de cette opération pourraient être appliqués à l'aide de la logique métier ailleurs dans l'application, mais l'abstraction ressemblerait à ceci:

Cette refactorisation, bien que petite, est la plus grande que nous ayons faite dans cet article. Notez que nous avons fait les choses suivantes:

  1. A créé un Informations de contact classe qui nous permet d'instancier un objet contenant toutes les informations de paiement d'une personne.
  2. A créé un Informations de paiement classe qui nous permet de conserver le numéro de carte de crédit ou de débit d'une personne ainsi que d'autres détails associés à ce mode de paiement.
  3. Créé un Ordre classe, placé le Soumettre la commande fonction à l'intérieur de celui-ci, l'a renommé pour soumettre (depuis Soumettre la commande redondant) et a réduit sa liste de paramètres à deux valeurs: une instance de Informations de contact la classe et la Informations de paiement classe).

Pour être clair, cet exemple ne traite pas la vérification de l'association entre les informations de contact et les informations de paiement, et ne montre pas d'autres classes qui peuvent être nécessaires (par exemple, si le paiement a échoué pour la transaction)..

Mais ce n'est pas le but de l'exercice.

Au lieu de cela, nous examinons l'odeur de code des longues listes de paramètres et la façon dont nous pouvons les réduire en utilisant des méthodes pratiques et plus faciles à gérer..

Chaque fois que vous écrivez une fonction ou appelez une fonction qui nécessite un grand nombre d'arguments, recherchez des moyens de la refactoriser. Cela fera augmenter la cohésion du code et diminuer les odeurs.

Conclusion

Rappelez-vous, les exemples que nous avons examinés ci-dessus ne sont que cela. La liste est loin d'être complète, mais ce sont des odeurs courantes que vous êtes susceptible de voir dans le code avec lequel vous travaillez ou même le code que vous écrivez. Je serai le premier à admettre que je suis coupable de cela.

De plus, de nombreuses ressources sont disponibles pour identifier et corriger les odeurs de code. Heureusement, nous disposons également de nombreux outils qui nous aideront à les découvrir automatiquement et à les nettoyer..

Et c'est là que nous nous dirigeons ensuite. Plus précisément, nous allons utiliser PHP CodeSniffer afin de nous aider à éviter les odeurs de code dans notre code. Ensuite, nous verrons comment incorporer les règles WordPress dans PHP CodeSniffer et le relier à notre IDE de choix.

Comme mentionné précédemment dans cet article, le prochain article de la série se concentrera davantage sur les odeurs de code lors de l'écriture de code pour WordPress. Nous allons examiner quelques outils et ressources disponibles pour nous aider à éviter les odeurs de code et pour nous assurer que nous écrivons du code plus puissant..

En attendant, étudiez les exemples ci-dessus et vérifiez les ressources que j'ai fournies. Ce sont d'excellents endroits pour en apprendre davantage sur les odeurs et le refactoring de code pour des personnes et des lieux remarquables de notre secteur.

N'oubliez pas que vous pouvez voir tous mes cours et tutoriels sur ma page de profil et vous pouvez me suivre sur mon blog et / ou Twitter à @tommcfarlin, où je parle de diverses pratiques de développement de logiciels et de la façon dont nous pouvons les utiliser dans WordPress..

S'il vous plaît n'hésitez pas à laisser des questions ou des commentaires dans le flux ci-dessous, et je vais essayer de répondre à chacun d'eux.