Comment écrire du code qui sera réutilisé



L'idée que le code conçu pour être réutilisé peut être une panacée pour tous les problèmes de programmation est un mythe dangereux. Je vais maintenant expliquer pourquoi.

Imaginons que vous écrivez une bibliothèque et que vous saisissez soudainement une idée brillante, à partir de laquelle une solution généralisée peut être obtenue, applicable dans un très large éventail de cas. Vous prescrivez fiévreusement des API qui domineront toute fonctionnalité et s'adapteront à n'importe quel scénario. Vous ajoutez tous les scripts qui vous viennent à l'esprit. Le code gonfle et gonfle, mais, finalement, il devient vraiment généralisé dans le sens le plus complet du mot. Il est comme des petits pains et tu es heureux.

Mais un jour, une nouvelle API émerge à l'horizon. Il est plus concis et adapté à un plus grand nombre de scénarios, et de plus, il gagne en rapidité et en simplicité. Votre API tombe dans l'oubli - tout le monde passe immédiatement à une nouveauté tentante. Cependant, après un certain temps, la même histoire se répète avec elle: l'API devient de plus en plus lourde en raison d'ajouts constants au code, conçus pour de nouvelles conditions, jusqu'à ce que finalement quelque chose d'autre vienne le remplacer. Et ainsi de suite à l'infini.

Pourquoi en est-il ainsi?

La racine de tous les problèmes dans ce cas est le désir d'écrire des solutions généralisées. Si le code reproductible prend un cas standard comme standard, il devient gonflé, peu pratique à utiliser et se transforme progressivement en un simple mal de tête.

Un certain degré de généralisation est une condition préalable à l'utilisation répétée de tout code. Mais si vous allez trop loin avec cela, l'utilitarisme commence à souffrir. Par conséquent, si j'exprime ma pensée en un mot, écrire un code réutilisable ne se résume pas à le rendre aussi complet que possible. Tout est beaucoup plus compliqué.
Pour créer un code reproductible pratique, vous devez vous assurer qu'il n'est pas utilisé régulièrement, mais spontanément, lorsque le besoin s'en fait sentir. Disons que lorsque vous travaillez sur un produit, vous rencontrez soudainement un code qui peut être utilisé pour ses besoins. Vous prenez cet extrait, le modifiez un peu et l'implémentez dans l'application. Ainsi, vous ne payez que pour ce qui est réellement avantageux, et exactement quand cela est nécessaire.

Plus tard, vous découvrez que cette version révisée peut être utile dans une autre application. Vous reprenez ce fragment, le modifiez légèrement et l'utilisez dans le troisième cercle. Ainsi, en augmentant progressivement la reproductibilité, vous obtenez non seulement le maximum d'avantages de ce fragment, mais vous protégez également votre produit contre du code qui ne fait rien pour lui et qui n'est généralement pas nécessaire en lui.

L'essentiel ici n'est en aucun cas d'essayer de prédire l'avenir. La reproductibilité doit être limitée aux limites de visibilité actuelles; à l'avenir, vous corrigerez le code en conséquence chaque fois qu'une nouvelle opportunité se présentera pour son application. Cela vous permettra non seulement d'économiser du temps et des efforts, mais également d'écrire du code plus économique, cool et moderne, affûté pour la réutilisation.

Voici quelques suggestions pratiques sur la façon de rendre le code réutilisable.

Évitez les doublons


Comme l'a dit à juste titre Lemony Sinquet: «Ne répétez pas. Premièrement, vous vous répétez, deuxièmement, vous dites la même chose, et troisièmement, tout le monde a déjà entendu cela. »

Rappelez-vous, nous avons parlé de réutilisation qui se produit spontanément? C'est exactement ce que (et seulement cela) devrait être limité à l'objectif du code ergonomique. Écrivez donc le code dont vous avez besoin à ce moment particulier et continuez dans le même esprit jusqu'à ce que vous remarquiez que vous devez résoudre le même problème encore et encore. Faites ensuite la refactorisation, placez le code dans un endroit accessible et faites-y référence si nécessaire. En agissant de cette manière, vous obtiendrez non pas un code généralisé inutile, mais un code dans lequel il n'y a pas de duplication.

En fait, le même principe est postulé par le principe DRY (ne vous répétez pas), qui stipule que la même logique ne doit pas être répétée dans le code - cela donne lieu à un devoir technique. Les répétitions insignifiantes obstruent le système, réduisent la qualité de la base de code et, en outre, le transforment en cauchemar pour ceux qui ont la responsabilité de maintenir le code du produit. Il est important de se souvenir: le principe DRY est une sorte de philosophie qui appelle à abandonner les ambitions de programmation personnelle et à faire ce qui est le mieux pour le projet. Si quelqu'un a déjà fait quelque chose, utilisez-le. Pas besoin de réinventer la roue.

Assurez-vous que la classe / méthode / fonction est responsable d'une chose.


A cette occasion, on peut rappeler la belle déclaration de Louis Sullivan: "La forme vient de la destination". En traduction, cela signifie ce qui suit: si une fonction, une classe ou une méthode fait la seule et unique chose, vous les modifierez pour une seule raison. Oui, avec cette approche, vous devrez souvent créer des méthodes qui utiliseront d'autres méthodes, mais elles resteront simples et pas trop cohérentes.

Chaque système est construit au moyen d'un langage orienté sujet, qui a été créé par des programmeurs dans le but de décrire correctement ces systèmes. Les fonctions remplissent le rôle des verbes dans ces langues, et les classes jouent le rôle des noms. Ensemble, ils forment, en règle générale, le niveau d'organisation de base de toute langue; par conséquent, si vous les prescrivez de manière qualitative, votre code sera de haute qualité.

Il existe deux règles d'or pour créer des fonctions et des classes qui peuvent être appliquées plusieurs fois, deux seulement:

  • Ils devraient être petits
  • Ils devraient faire une chose, et bien

Cela suppose que la fonction ne doit pas croître suffisamment pour contenir des structures imbriquées. Le niveau de nidification ne doit donc pas dépasser un ou deux. Grâce à cette technique, le code devient plus facile à lire, à analyser et à assimiler.

De plus, il est nécessaire de s'assurer que tous les opérateurs au sein d'une même fonction restent au même niveau d'abstraction. Mélanger les niveaux est toujours déroutant et tôt ou tard, cela entraînera un travail acharné avec le code. Les programmeurs professionnels voient le code reproductible comme une sorte de récit, pas seulement un morceau de texte. Ils utilisent les capacités du langage de programmation choisi pour créer des blocs plus expressifs, significatifs et soignés qui construisent parfaitement le récit.

Ne pas abuser de l'héritage


Parfois, nous, les développeurs, essayons de regarder dans le futur lointain du projet et commençons à ajouter des fonctions supplémentaires avec les pensées «et si vous en avez besoin» et «un jour vous seront utiles». Ne fais pas ça. Jusqu'à présent, cela ne vous a pas été utile, maintenant vous n'en avez pas besoin et dans la plupart des cas ... vous n'en aurez pas besoin (pour paraphraser le principe bien connu de YAGNI - Vous n'en aurez pas besoin). Ce principe s'applique à l'héritage. N'y entrez pas si vous n'êtes pas sûr que la mise en œuvre sera répétée plusieurs fois.

Avec tout cela, l'hérédité est un excellent moyen d'ajouter des fonctionnalités à une classe. Mais les programmeurs ont tendance à prendre le dessus, créant des hiérarchies de classes à six niveaux ou plus. Le «Gang of Four» dans son livre «Design Patterns» décrit succinctement les risques d'héritage excessif:

"Puisque la sous-classe a accès aux détails d'implémentation de la classe parente, il est souvent dit que l'héritage viole l'encapsulation."

L'hérédité conduit à une forte cohésion des composants, car la superclasse ouvre ses intérieurs aux sous-classes, et ceux-ci, à leur tour, dépendent complètement de la superclasse dans tout ce qui concerne le bon fonctionnement. Dans cette situation, la superclasse perd sa flexibilité - il devient difficile de changer quoi que ce soit dans sa fonctionnalité. Pour cette raison même, l'hérédité est un mauvais moyen de réutiliser le code.

Une approche plus raisonnable consiste à penser dans le paradigme de la structure des objets, plutôt que de l'hérédité. Cela permettra aux utilisateurs de votre code de saisir plus facilement exactement les fonctionnalités dont ils ont besoin et de créer leurs propres objets en fonction des restrictions qui les concernent. Vous devriez même envisager de créer des interfaces procédurales que chacune des classes peut implémenter à sa manière. Les interfaces sont souvent plus faciles à comprendre et à implémenter que les classes avec héritage multicouche.

Pour résumer, on ne devrait recourir à l'hérédité que si une classe est la continuation logique d'une autre et la plupart du code de la classe héritière utilise le code de la superclasse. Dans tous les autres cas, vous signez simplement la peine de mort pour vous-même et les chances de votre code de réutilisation.

En conclusion


En général, écrire du code pour la réutilisation ne signifie pas créer d'énormes blocs monolithiques généralisés. La clé pour écrire du code reproductible réside dans les éléments qui visent une tâche spécifique, qui sont facilement assemblés, bien soudés et pas trop solidement interconnectés.

Et enfin, ne vous arrêtez pas en soi à une utilisation répétée - cela n'en vaut pas la peine. Il est préférable de fixer un objectif pour éviter la duplication, de ne pas écrire de fragments vides et inutiles, pour garantir que le code est facile à lire et à maintenir. Lorsque vous développez la bonne vision des choses, la reproductibilité viendra d'elle-même.

Rappelez-vous toujours: la réutilisation commence par le fait que vous avez trouvé une solution réussie pour une tâche particulière. Tout le reste devrait découler de cette prémisse, et vous avez le droit de choisir la méthode la plus appropriée afin d'amener un certain morceau de code à un nouveau niveau. Comme Ralph Johnson l'a fait remarquer à juste titre: «Avant de penser à réutiliser du code, vous devez vous assurer que vous pouvez l'utiliser.»

Source: https://habr.com/ru/post/fr481296/


All Articles