Comment rouler avec un code hérité lorsqu'un projet était nécessaire hier

Salut Je m'appelle Ivan Melnichuk, je suis chef du département de développement dans une société informatique ukrainienne. Dans la publication, je veux partager mes approches professionnelles personnelles concernant la résolution du problème de code hérité dans le contexte du développement rapide du projet et parler des techniques auxquelles notre équipe a recours dans les cas «lorsque des fonctionnalités doivent être transmises» pour hier ».

Nous nous occupons du projet


Afin de montrer à quel point le travail doit être précis, réfléchi et minutieux avec l'héritage, je donnerai une analogie avec un château de cartes.

image

Voici à quoi ressemble le code hérité. Si nous décidons de retirer ou de remplacer au moins une carte de ce bâtiment, nous courons le risque de submerger toute la maison et de niveler ses restes avec le sol.

Legacy se comporte approximativement de la même manière. Par conséquent, le travail d'un programmeur qui a assumé la tâche de moderniser et de «donner une seconde vie» au projet devrait être dans une certaine mesure un bijou. La plupart des programmeurs tentent d'éviter et généralement de «sauter du sujet» de la dette technique. Même compilé un hit-parade des citations les plus courantes qui devaient être entendues par des programmeurs pris dans des conditions héritées:

  1. Nous avons créé un site "simple", et maintenant vous voulez obtenir un nouveau "chignon", et nous devons réécrire tout cela, car nous avons un héritage ...
  2. Personne ne sait comment cela fonctionne ..
  3. Pour ajouter un module, vous devez vérifier l'ensemble du site - seulement de cette façon, nous comprendrons quoi et où il peut sortir ...
  4. Je ne vais pas y aller en tout cas, tout y est déjà mal ...

Mais l'expérience en programmation montre que la vie après l'héritage existe. Il n'y a aucun problème de programmation. Il n'y a que des tâches qui doivent être traitées. Et avant d'élaborer un plan d'action «pour surmonter le code d'héritage», vous devez comprendre à quel point les choses sont mauvaises sur le projet dans son ensemble. Au cours de la pratique, il a identifié 6 étapes du problème du projet:

  1. Pas de documentation technique. Le seuil de problèmes le plus bas, car vous pouvez tester et en venir à des hypothèses préliminaires sur la façon dont cela devrait fonctionner.
  2. Pas de documentation commerciale. Si toute la documentation (à la fois technique et commerciale) est manquante, le sentiment «il semble que nous sommes coincés dans l'histoire» vient involontairement. En effet, même une entreprise ne se souvient pas de la façon dont elle devrait fonctionner, ce qui signifie que l'équipe, au moins, n'a aucune compréhension du résultat attendu.
  3. Personne n'a conçu cela. Si, en plus du manque de documentation, il n'y a pas non plus de développeur qui pourrait expliquer comment le projet devrait fonctionner, alors ça sent déjà frit.
  4. Nous ne savons pas ce que l'utilisateur devrait finalement obtenir. C'est une chose lorsque seuls les problèmes liés au back-end se posent, mais si nous n'avons toujours aucune idée de ce qui doit être affiché à l'avant, cela est déjà proche de l'état «le patient est plus susceptible d'être mort que vivant».
  5. 200+ utilisation de chaque fonction et elles sont appelées getA . Cinquième niveau de difficulté: lorsque vous entrez dans Legacy, vous voyez l'utilisation des fonctions A et 200, et personne ne sait pourquoi c'est ...
  6. Il n'y a aucun programmeur qui souhaiterait / pourrait développer. Pas de commentaire.

Comprendre les affaires


Les entreprises comptent pour l'argent. Les entreprises ne veulent pas dépenser des ressources financières supplémentaires simplement pour refaire ce qui fonctionne déjà. Une entreprise n'achètera jamais l'idée: «Je vais le faire d'une manière nouvelle parce que je n'aime pas ça.» Par conséquent, offrez toujours plus.

Souvent, les développeurs poussent les entreprises vers des idées inutiles. À cette occasion, il existe un «fonds de citations d'or» distinct.

  • Nous embauchons une nouvelle équipe pour un «sciage» de haute qualité du code. Autrement dit, nous avons besoin d'une équipe de spécialistes qui réalisera le projet en parallèle avec l'équipe existante. Pas le fait que le résultat sera différent, mais l'entreprise devrait déjà contenir deux projets.
  • Nous arrêtons d'ajouter des fonctionnalités, maintenant seulement la refactorisation! Officiellement, vous déclarez aux entreprises: tabou absolu sur les fonctionnalités, il est seulement possible de "mettre les choses en ordre" sous le capot. Officieusement, vous avez dit qu'il n'y aura pas d'améliorations et d'améliorations à grande échelle du projet, mais que vous les «réparerez» localement.
  • J'ai déjà tout ce dont j'ai besoin sur WP, j'ai juste besoin de migrer la base de données. Il s'agit d'un «symptôme» d'un débutant. La chanson préférée de June: c'est un site tellement simple, ça ne marche qu'une heure ou deux ...

Pour négocier avec l'entreprise concernant la réincarnation d'un code obsolète, servi sous la sauce de nouvelles fonctionnalités rentables, il faut partir de la position d'ouvrir de nouveaux horizons commerciaux. Cependant, avant les négociations, il faut répondre aux questions suivantes:

  1. L'entreprise est-elle prête à croître? Vous devez comprendre: l'entreprise a-t-elle une demande d'élever la norme financière ou a-t-elle simplement besoin du service pour travailler plus efficacement?
  2. Stade du prototype? Souvent, une entreprise commande un prototype simple, avec lequel elle veut «sonder» le marché au moment de la pertinence du produit. Et ce n'est que s'il commence à gagner de l'argent que l'entreprise est prête à développer la fonctionnalité en un projet plus avancé et complet.
  3. Le développement est-il terminé et désormais uniquement support? Il est important de comprendre la gamme complète des tâches.
  4. Y a-t-il suffisamment de feu dans nos yeux et ne s'éteindra-t-il pas? Le projet doit inspirer et non démotiver. Il est très important que votre équipe souhaite s'engager dans la réincarnation de Legacy, sinon les gens se disperseront progressivement dans des projets plus intéressants pour eux.
  5. Y a-t-il un architecte? C'est la question la plus importante - avez-vous une personne qui peut faire la bonne architecture et commencer à écrire du bon code déjà. Cela n'a aucun sens d'essayer même de commencer s'il n'y a pas d'architecte. Sinon, dans une semaine, vous deviendrez celui qui a créé l'héritage du problème.

Lorsque vous vendez des idées aux entreprises, concentrez-vous sur les messages "nouveau, créer, ajouter" ... L'entreprise répond très bien aux offres de la série: "Nous vous ferons une nouvelle fonctionnalité et le projet X sera plus rapide ..." et "Pour augmenter la conversion, ajoutez-en une nouvelle ... "

P - Planification


Pour travailler rapidement et efficacement avec la dette technique, vous avez besoin d'un plan.

1. Définition des tâches sur lesquelles nous parasiterons. Pourquoi parasiter? Cela arrive souvent: nous avons vendu une fonctionnalité, et par là, nous entendons partiellement le refactoring.

2. Définition d'exigences de haut niveau. Il est nécessaire d'enregistrer une demande commerciale claire pour un «standard élevé» afin d'établir la documentation correcte.

3. Définition des principaux modules du système, imposition de modules. Avant de commencer la refactorisation, vous devez comprendre les principaux modules du système: où, comment, quoi et avec quoi peuvent interagir et délimiter le code en sections.

4. Définition de l'intégration. Lors de la création d'un module spécifique, nous devons penser à l'avance à la possibilité de le monter dans un héritage voisin.

5. Définition de l'équipe. Un dans le domaine du refactoring n'est pas un guerrier. L'équipe est un élément très important d'un résultat réussi. Ferveur, esprit d'équipe et excellente interaction entre les participants au processus indispensable.

6. Comment allons-nous tester? Si vous envisagez de prendre un projet de haute qualité, vous devez penser à l'avance et proposer des options de test de produit.

Parallèlement à ce qui précède, il est également important de déterminer quel devrait être le résultat final souhaité, d'élaborer un plan de mise à l'échelle et d'enregistrer les goulots d'étranglement du projet. Par exemple, en cas de mise à l'échelle de code, il est important de comprendre où des problèmes peuvent potentiellement survenir dans des conditions de forte charge (il peut s'agir d'une base de données, ou de requêtes lourdes, ou d'une grille, ou d'un autre lien intermédiaire qui peut «tomber»).

Il est tout aussi important de déterminer les limites du projet, où se trouvait l'ancien code et où il y aura un nouveau niveau de «chef-d'œuvre». Vous devriez également envisager des approches de microservices, ou DDD, ou, peut-être, vous avez besoin d'un peu plus de «nanomagie».

Ninja Legacy Techniques


Après le «travail préparatoire», nous arrivons aux techniques qui facilitent le processus d'épargne de la dette technique. Il n'y a pas de recette universelle et de panacée pour tous les maux dans Legacy, mais au cours de travaux sur des projets à forte charge, j'ai fait une liste d'ingrédients avec lesquels vous pouvez préparer un code vraiment «savoureux».

1. Ne réinventez pas la roue. Pour moi, c'est le principal hack de vie pour écrire du code. Tout a été inventé avant vous, ne recourez pas à la danse avec des tambourins et autres expériences pour résoudre les problèmes de code hérité.

2. Le code est standard. Sans standard unique, chaque développeur écrira à sa manière. Le «style d'auteur» contribuera au chaos et augmentera encore plus la corbeille de code.

3. Révision du code. Pas seulement une présence de la norme de code. Il est également nécessaire que l'équipe soit chargée de le vérifier. Sinon, tout reviendra à la normale, c'est-à-dire au niveau de l'ancien code.

4. Analyseurs de code statique, détecteur de dégâts PHP, etc. (au lieu d'un millier de livres) . Ces techniques et d'autres techniques automatiques seront nécessaires pour accélérer le processus, en particulier avec le même code de révision.

5. Nous essayons les microservices. Séparément, il peut également y avoir des modules ou des bibliothèques. Pourquoi des microservices? Leur avantage est d'isoler autant que possible la logique et de la limiter à une API spécifique. L'avantage de ce dernier est que l'API est une entité plus monolithique par rapport à «l'adaptateur dans le code qui peut être corrigé». Cependant, l'API présente un inconvénient sous la forme de coûts réseau supplémentaires.

6. Architecture de base de données, sources de données. C'est la base de données que je considère comme le premier goulot d'étranglement de tout héritage. Mais tout le monde conçoit comme il veut, et même en SQL, vous pouvez trouver des défauts non focalisés. Voici quelques conseils pour travailler avec la nouvelle base de données:

  • Rien à foutre, soif de tout. Si vous souhaitez modifier l'ancienne structure de données incorrecte en un nouveau format de données, plus rapide et plus productif, vous pouvez procéder de deux manières. La première consiste à installer une nouvelle base, en supprimant complètement l'ancienne et quoi qu'il arrive. La seconde - dans le cas d'un héritage dur, introduire un nouveau format en parallèle. Au sens figuré, pour en planter un nouveau près d'un vieil arbre. Pourquoi la deuxième voie est-elle justifiée et plus prometteuse? Parce que tout ce qui est nouveau fonctionnera efficacement et si des problèmes surviennent pendant la phase de déploiement ou d'intégration, vous pouvez simplement restaurer le code et il n'est pas nécessaire de restaurer toutes les migrations de bases de données complexes.
  • Une nouvelle base de données est créée dans la structure correcte. Lors de la création d'une nouvelle ressource, il est important de contrôler les endroits dans lesquels nous écrivons la nouvelle structure. En parallèle, il est nécessaire de créer un support pour l'ancienne structure, car il n'est pas pratique de s'en débarrasser complètement. Autrement dit, nous continuons à écrire du nouveau matériel, et en même temps, nous soutenons l'ancien modèle, dans lequel nous traduisons tout ce qui est nouveau, et permettons ainsi à l'ancien de fonctionner aussi - comme si à l'ancienne, mais en soutenant la nouvelle structure.
  • Nous contrôlons l'ensemble de l'enregistrement. Nous ne manquons pas les détails du champ d'attention afin de garantir le support de la base de données.

7. Mais SQL? Si, d'un point de vue architectural, vous pouvez opérer avec des entités, opérez. Le concept de quelque chose de défini et de fini vous aidera à ne pas créer de relations inutiles et en double.

8. Décorateurs, adaptateurs, médiators ... Ces modèles sont l'un des principaux pour intégrer le nouveau code dans l'ancien héritage.

9. Plan B, ou plan de restauration pour l'intégration. Beaucoup font l'erreur de l'oublier. Il est vital dans la situation «quand quelque chose ne va pas» lors de la coulée de nouveau matériel. Autrement dit, dès que nous commençons à construire l'architecture, déjà à ce stade, nous devons comprendre comment nous allons la restaurer en cas de bogue.

10. Un nouveau code sans (docks) tests devient un héritage en une semaine. Peu importe la beauté de votre code, sans documentation dans une semaine, il sera dans le statut «hérité» - en raison de son incompréhensibilité.

11. Test. Si les tests unitaires sont trop chers, nous utilisons des tests de fumée, fonctionnels et d'intégration. Dans quelle mesure est-il réaliste de vendre des tests unitaires à une entreprise avec de la sauce «pour rendre un travail beau?» Dans nos réalités, c'est plutôt une rareté qu'un modèle. Si pour une raison quelconque, cela ne fonctionne pas avec des «unités», nous nous tournons vers des tests de fumée, fonctionnels ou d'intégration, et n'oubliez pas que nous pouvons déléguer la tâche, par exemple, à un testeur manuel.

Au lieu d'un épilogue


La chose la plus importante dans cette histoire est de faire le travail et de ne pas laisser l'héritage de 6 étapes problématiques (classées par ordre de simple à plus complexe):

  • Pas de documentation technique
  • Pas de documentation commerciale
  • Il n'y a personne qui a développé ce
  • Nous ne savons pas ce que l'utilisateur devrait recevoir.
  • 200 + utilisation de chaque fonction et elles sont appelées getA ()
  • Il n'y a personne qui voudrait / pourrait développer cela.

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


All Articles