web-dev-qa-db-fra.com

Comment garder un produit logiciel grand et complexe maintenable au fil des ans?

Je travaille en tant que développeur de logiciels depuis de nombreuses années maintenant. D'après mon expérience, les projets deviennent plus complexes et irréalisables à mesure que de plus en plus de développeurs s'impliquent dans le développement du produit.

Il semble que les logiciels à un certain stade de développement aient tendance à devenir "plus hackers" et "hackiers", surtout quand aucun des membres de l'équipe qui a défini l'architecture ne travaille plus dans l'entreprise.

Je trouve frustrant qu'un développeur qui doit changer quelque chose ait du mal à avoir une vue d'ensemble de l'architecture. Par conséquent, il existe une tendance à résoudre les problèmes ou à apporter des modifications d'une manière qui fonctionne contre l'architecture d'origine. Le résultat est un code qui devient de plus en plus complexe et encore plus difficile à comprendre.

Y a-t-il des conseils utiles sur la façon de maintenir le code source vraiment maintenable au fil des ans?

157
chrmue

La seule vraie solution pour éviter la pourriture du code est de bien coder!

Comment bien coder est une autre question. C'est déjà assez difficile même si vous êtes un excellent programmeur travaillant seul. Dans une équipe hétérogène, cela devient encore plus difficile. Dans les (sous) projets externalisés ... priez simplement.

Les bonnes pratiques habituelles peuvent aider:

  1. Rester simple.
  2. Rester simple. Cela vaut en particulier pour l'architecture, la "vue d'ensemble". Si les développeurs ont du mal à avoir une vue d'ensemble, ils vont coder contre. Rendez donc l'architecture simple pour que tous les développeurs l'obtiennent. Si l'architecture doit être moins que simple, alors les développeurs doivent être formés pour comprendre cette architecture. S'ils ne l'intériorisent pas, ils ne devraient pas y coder.
  3. Visez faible couplage et forte cohésion . Assurez-vous que tous les membres de l'équipe comprennent cette idée. Dans un projet composé de parties cohésives lâchement couplées, si certaines parties deviennent un gâchis irréalisable, vous pouvez simplement débrancher et réécrire cette partie. C'est plus difficile ou presque impossible si l'accouplement est serré.
  4. Être cohérent. Les normes à suivre importent peu, mais veuillez suivre certaines normes . Dans une équipe, tout le monde doit bien sûr suivre les mêmes standards. D'un autre côté, il est facile de s'attacher trop aux normes et d'oublier le reste: veuillez comprendre que si les normes sont utiles, elles ne sont qu'une petite partie de la création d'un bon code. N'en faites pas un grand nombre.
  5. Revues de code peut être utile pour faire travailler une équipe de manière cohérente.
  6. Assurez-vous que tous les outils - IDE, compilateurs, contrôle de version, systèmes de construction, générateurs de documentation, bibliothèques, ordinateurs , les chaises , l'environnement global etc. etc. - sont bien entretenues pour que les développeurs n'aient pas à perdre leur temps avec des problèmes secondaires tels que la lutte contre les conflits de version de fichier de projet, les mises à jour Windows, le bruit et tout ce qui est banal mais irritant. Devoir perdre à maintes reprises un temps considérable avec de telles choses inintéressantes abaisse le moral, ce qui au moins n'améliorera pas la qualité du code. Dans une grande équipe, il pourrait y avoir un ou plusieurs gars dont la tâche principale est de maintenir les outils de développement.
  7. Lorsque vous prenez des décisions technologiques, pensez à ce qu'il faudrait pour changer de technologie; quelles décisions sont irréversibles et lesquelles ne le sont pas. Évaluez soigneusement les décisions irréversibles. Par exemple, si vous décidez d'écrire le projet en Java , c'est une décision à peu près irréversible. Si vous décidez d'utiliser un format binaire auto-bouilli pour les fichiers de données, c'est également une décision assez irréversible (une fois que le code est sorti dans la nature et que vous devez continuer à prendre en charge ce format). Mais les couleurs de l'interface graphique peuvent être facilement ajustées, les fonctionnalités initialement omises peuvent être ajoutées plus tard, donc insistez moins sur ces problèmes.
138
Joonas Pulakka

Tests unitaires sont vos amis . Leur mise en œuvre force un faible couplage. Cela signifie également que les parties "hacky" du programme peuvent être facilement identifiées et refactorisées. Cela signifie également que toutes les modifications peuvent être testées rapidement pour s'assurer qu'elles ne cassent pas les fonctionnalités existantes. Cela devrait encourager vos développeurs à modifier les méthodes existantes plutôt que de dupliquer le code de peur de casser les choses.

Les tests unitaires fonctionnent également comme une documentation supplémentaire pour votre code, décrivant ce que chaque partie doit faire. Avec des tests unitaires étendus, vos programmeurs ne devraient pas avoir besoin de connaître toute l'architecture de votre programme pour apporter des modifications et utiliser les classes/méthodes existantes.

En tant qu'effet secondaire agréable, les tests unitaires permettront également, espérons-le, de réduire le nombre de bogues.

55
Tom Squires

Tout le monde ici est rapide à mentionner code rot, et je comprends parfaitement et suis d'accord avec cela, mais il manque toujours la vue d'ensemble et le plus gros problème à portée de main ici. La pourriture de code ne se produit pas simplement. De plus, des tests unitaires sont mentionnés, ce qui est bien, mais ils ne résolvent pas vraiment le problème. On peut avoir une bonne couverture de test unitaire et un code relativement exempt de bogues, mais avoir encore du code et une conception pourris.

Vous avez mentionné que le développeur travaillant sur un projet a du mal à implémenter une fonctionnalité et manque une vue d'ensemble de l'architecture globale, et implémente donc un hack dans le système. Où est le leadership technique pour appliquer et influencer la conception? Où sont les revues de code dans ce processus?

Vous ne souffrez pas réellement de pourriture de code, mais vous souffrez de pourriture d'équipe. Le fait est que cela ne devrait pas avoir d'importance si les créateurs originaux du logiciel ne font plus partie de l'équipe. Si le responsable technique de l'équipe existante comprend pleinement et vraiment la conception sous-jacente et est bon dans le rôle de responsable technique, alors ce ne sera pas un problème.

40
maple_shaft

Nous pouvons faire plusieurs choses:

Donnez à une personne la responsabilité globale de l'architecture. Lorsque vous choisissez cette personne, assurez-vous qu'elle a la vision et les compétences nécessaires pour développer et maintenir une architecture, et qu'elle a l'influence et l'autorité nécessaires pour aider d'autres développeurs à suivre l'architecture. Cette personne doit être un développeur chevronné auquel la direction fait confiance et qui est respecté par ses pairs.

Créez une culture où tous les développeurs s'approprient l'architecture. Tous les développeurs doivent être impliqués dans le processus de développement et de maintien de l'intégrité architecturale.

Développer un environnement où les décisions architecturales sont facilement communiquées. Encouragez les gens à parler de design et d'architecture - pas seulement dans le contexte du projet actuel, mais en général aussi.

Les meilleures pratiques de codage facilitent la visualisation de l'architecture à partir du code - prenez le temps de refactoriser, de commenter le code, de développer des tests unitaires, etc. pour prendre le temps de développer et de suivre vos propres normes.

Assurez-vous que toute la documentation nécessaire est claire, concise, à jour et accessible. Rendez les diagrammes d'architecture de haut et de bas niveau publics (les épingler au mur peut aider) et publiquement maintenables.

Enfin (en tant que perfectionniste naturel), je dois reconnaître que l'intégrité architecturale est une aspiration digne, mais qu'il peut y avoir des choses plus importantes - comme la constitution d'une équipe qui peut bien travailler ensemble et réellement expédier un produit fonctionnel.

18
Kramii

La façon dont je traite ce problème est de le couper à la racine:

Mon explication utilisera des termes de Microsoft/ . NET , mais sera applicable à toute plate-forme/boîte à outils:

  1. Utilisez des normes de dénomination, de codage, de consignation, de flux de bogues, de flux de processus - pratiquement tout.
  2. N'ayez pas peur de dire au revoir aux membres de l'équipe qui ne respectent pas les normes. Certains développeurs ne peuvent tout simplement pas travailler dans un ensemble défini de normes et deviendront les ennemis de la 5e colonne sur le champ de bataille pour garder la base de code propre
  3. N'ayez pas peur d'affecter des membres de l'équipe moins qualifiés aux tests pendant de longues périodes.
  4. Utilisez tous les outils de votre arsenal pour éviter de consigner le code pourri: cela implique des outils dédiés, ainsi que des pré-écrits tests unitaires qui testent les fichiers de construction, les fichiers de projet, la structure des répertoires, etc.
  5. Dans une équipe d'environ 5-8 membres, demandez à votre meilleur gars de refactoriser presque constamment - nettoyer le désordre que les autres laissent derrière eux. Même si vous trouvez les meilleurs spécialistes dans le domaine, vous aurez toujours un gâchis - c'est inévitable, mais il peut être contraint par le refactoring constant.
  6. Faites des tests unitaires et maintenez-les - ne dépendez PAS des tests unitaires pour garder le projet propre, ils ne le font pas.
  7. Discutez de tout. N'ayez pas peur de passer des heures à discuter des choses en équipe. Cela diffusera les informations et supprimera l'une des causes profondes du mauvais code: confusion sur les technologies, les objectifs, les normes, etc.
  8. Soyez très prudent avec les consultants qui écrivent du code: leur code sera, presque par définition, le vrai truc de merde.
  9. Examinez de préférence comme étape du processus avant l'enregistrement. N'ayez pas peur d'annuler les commits.
  10. N'utilisez jamais le principe d'ouverture/fermeture sauf dans la dernière étape avant la sortie: cela conduit simplement à laisser le code pourrir à sentir.
  11. Chaque fois qu'un problème est rencontré, prenez le temps de le comprendre pleinement avant d'implémenter une solution - la majeure partie de la pourriture de code provient de l'implémentation de la solution à des problèmes qui ne sont pas entièrement compris.
  12. Utilisez les bonnes technologies. Celles-ci viendront souvent en ensembles et seront fraîches: il vaut mieux dépendre d'une version bêta d'un framework dont vous serez assuré le support à l'avenir, que de compter sur des frameworks extrêmement stables, mais obsolètes, qui ne sont pas pris en charge.
  13. Embauchez les meilleures personnes.
  14. Mettez à pied le reste - vous ne dirigez pas un café.
  15. Si la direction n'est pas la meilleure architecte et qu'elle interfère dans le processus décisionnel - trouvez un autre emploi.
18
casper

Nettoyez le code pourri en refactorisant, tout en écrivant des tests unitaires. Remboursez (ceci) la dette de conception sur tout le code que vous touchez, chaque fois que vous:

  • Développer une nouvelle fonctionnalité
  • Résoudre un problème

Accélérez considérablement votre cycle de développement test-first en:

  • Refactoring pour convertir des modules de code en langage de script
  • Utilisez des machines de test rapides basées sur le cloud

Code refactor pour utiliser un faible couplage (d'unités à cohésion interne élevée) en:

  • Fonctions (routines) plus simples et (plus)
  • Modules
  • Objets (et classes ou prototypes)
  • Fonctions pures (sans effets secondaires)
  • Privilégier la délégation plutôt que l'héritage
  • Couches (avec API)
  • Collections de petits programmes à but unique qui peuvent fonctionner ensemble

La croissance organique est bonne; la grande conception initiale est mauvaise.

Ayez un leader qui connaît la conception actuelle. Sinon, lisez le code du projet jusqu'à ce que vous soyez bien informé.

Lire des livres de refactorisation.

12
MarkDBlackwell

Réponse simple: vous ne pouvez pas.

C'est pourquoi vous devriez viser l'écriture de logiciels petits et simples. Ce n'est pas facile.

Cela n'est possible que si vous réfléchissez suffisamment à votre problème apparemment complexe pour le définir de la manière la plus simple et concise possible.

La solution à des problèmes véritablement importants et complexes peut souvent être résolue en s'appuyant sur des modules petits et simples.

En d'autres termes, comme d'autres l'ont souligné, la simplicité et le couplage lâche sont les ingrédients clés.

Si ce n'est pas possible ou faisable, vous faites probablement de la recherche (problèmes complexes sans aucune solution simple connue, ou aucune solution connue du tout). Ne vous attendez pas à ce que la recherche produise directement des produits maintenables, ce n'est pas à cela que sert la recherche.

11
Joh

Je travaille sur une base de code pour un produit qui est en développement continu depuis 1999, donc comme vous pouvez l'imaginer, c'est assez complexe maintenant. La plus grande source de piratage dans notre base de code provient des nombreuses fois où nous avons dû le porter de ASP Classic à ASP.NET , de ADO vers ADO.NET, des publications à Ajax , changement de bibliothèques d'interface utilisateur, normes de codage, etc.

Dans l'ensemble, nous avons fait un travail raisonnable pour maintenir la base de code maintenable. Les principales choses que nous avons faites qui y ont contribué sont:

1) Refactoring constant - Si vous devez toucher un morceau de code qui est hacky ou difficile à comprendre, vous devez prendre le temps supplémentaire pour nettoyer il et ont la latitude dans le calendrier pour le faire. Les tests unitaires rendent cela beaucoup moins effrayant, car vous pouvez tester plus facilement les régressions.

2) Gardez un environnement de développement soigné - Soyez vigilant sur la suppression du code qui n'est plus utilisé, et ne laissez pas de copies de sauvegarde/copies de travail/code expérimental existent dans le répertoire du projet.

3) Normes de codage cohérentes pour la durée de vie du projet - Avouons-le, nos opinions sur les normes de codage évoluent avec le temps. Je vous suggère de vous en tenir à la norme de codage avec laquelle vous avez commencé pour la durée de vie d'un projet, sauf si vous avez le temps de revenir en arrière et de moderniser tout le code pour vous conformer à la nouvelle norme. C'est génial que vous ayez fini notation hongroise maintenant, mais appliquez cette leçon à de nouveaux projets et ne vous contentez pas de basculer à mi-chemin sur ce nouveau projet.

9
JohnFx

Depuis que vous avez marqué la question avec la gestion de projet, j'ai essayé d'ajouter des points non codés :)

  • Planifiez le chiffre d'affaires - supposez que toute l'équipe de développement aura disparu au moment où elle atteindra sa phase de maintenance - aucun développeur digne de ce nom ne veut être bloqué pour maintenir son système pour toujours. Commencez à préparer le matériel de transfert dès que vous en avez le temps.

  • La cohérence/l'uniformité ne peut pas être suffisamment soulignée. Cela découragera une culture de "faire cavalier seul" et encouragera les nouveaux développeurs à demander s'ils sont dans le doute.

  • Gardez-le courant - technologies utilisées, modèles de conception et normes - car un nouveau développeur au sein de l'équipe (à tous les niveaux) aura plus de chances d'être opérationnel rapidement.

  • Documentation - en particulier l'architecture - pourquoi les décisions ont été prises et les normes de codage. Conservez également des références/notes/feuilles de route dans la documentation du domaine commercial - vous seriez étonné de la difficulté pour les entreprises à expliquer ce qu'elles font à un développeur sans expérience du domaine.

  • Établissez clairement les règles - pas seulement pour votre équipe de développement actuelle, mais pensez aux futurs développeurs de maintenance. Si cela signifie mettre un lien hypertexte vers la documentation de conception et de codage pertinente sur chaque page, qu'il en soit ainsi.

  • Assurez-vous que l'architecture et en particulier les couches de code sont clairement délimitées et séparées - cela permettra potentiellement le remplacement des couches de code à mesure que de nouvelles technologies se présenteront, par exemple, remplacer une interface utilisateur Web Forms par une HTML5 - jQuery UI , etc., qui peut acheter environ un an de longévité supplémentaire.

8
StuartLC

Une propriété du code hautement maitainable est la pureté de la fonction .

La pureté signifie que les fonctions doivent retourner le même résultat pour les mêmes arguments. Autrement dit, ils ne devraient pas dépendre des effets secondaires d'autres fonctions. De plus, cela est utile s'ils n'ont pas d'effets secondaires eux-mêmes.

Cette propriété est plus facile à observer que les propriétés de couplage/cohésion. Vous n'avez pas à faire tout votre possible pour y parvenir, et je considère personnellement que cela a plus de valeur.

Lorsque votre fonction est pure, son type est en soi une très bonne documentation. De plus, l'écriture et la lecture de la documentation en termes d'arguments/valeur de retour est beaucoup plus facile que celle mentionnant un état global (éventuellement accessible par d'autres threads O_O).

Comme exemple d'utilisation intensive de la pureté pour faciliter la maintenabilité, vous pouvez voir GHC . Il s'agit d'un grand projet d'environ 20 ans où de grands refactorisations sont en cours et de nouvelles fonctionnalités majeures sont encore en cours d'introduction.

Enfin, je n'aime pas trop le point "Keep it simple". Vous ne pouvez pas garder votre programme simple lorsque vous modélisez des choses complexes. Essayez de créer un compilateur simple et votre code généré se terminera probablement lentement. Bien sûr, vous pouvez (et devriez) simplifier des fonctions individuelles, mais l'ensemble du programme ne sera pas simple en conséquence.

7
Rotsor

Étant donné que bon nombre de ces réponses semblent se concentrer sur les grandes équipes, même dès le départ, je vais mettre mon point de vue au sein d'une équipe de développement de deux personnes (trois si vous incluez le concepteur) pour une startup.

De toute évidence, les conceptions et les solutions simples sont les meilleures, mais lorsque vous avez le gars qui paie littéralement votre salaire dans le cou, vous n'avez pas nécessairement le temps de penser à la solution la plus élégante, simple et maintenable. Dans cet esprit, mon premier gros point est:

Documentation Pas des commentaires, le code devrait être principalement auto-documenté, mais des choses comme les documents de conception, les hiérarchies et les dépendances de classe, les paradigmes architecturaux, etc. Tout ce qui aide un nouveau programmeur, ou même existant, à comprendre la base de code . En outre, la documentation de ces pseudo-bibliothèques étranges qui apparaissent finalement, comme "ajouter cette classe à un élément pour cette fonctionnalité" peut aider, car elle empêche également les gens de réécrire la fonctionnalité.

Cependant, même si vous avez un délai très court, je trouve qu'une autre bonne chose à garder à l'esprit est:

Évitez les hacks et des solutions rapides. À moins que la solution rapide ne soit la solution réelle, il est toujours préférable de déterminer le problème sous-jacent à quelque chose, puis de le résoudre. À moins que vous n'ayez littéralement un scénario "faites en sorte que cela fonctionne dans les 2 prochaines minutes, ou que vous soyez renvoyé", faire le correctif maintenant est une meilleure idée, car vous n'allez pas corriger le code plus tard, vous allez simplement passez à la prochaine tâche que vous avez.

Et mon astuce préférée personnelle est plus une citation, bien que je ne me souvienne pas de la source:

"Codez comme si la personne qui vient après vous est un psychopathe homicide qui sait où vous vivez"

6
Aatch

En plus des autres réponses, je recommanderais des couches. Pas trop mais assez pour séparer différents types de code.

Nous utilisons un modèle d'API interne pour la plupart des applications. Il existe une API interne qui se connecte à la base de données. Ensuite, une couche UI . Différentes personnes peuvent travailler à chaque niveau sans perturber ou casser d'autres parties des applications.

Une autre approche consiste à lire tout le monde comp.risks et The Daily WTF afin qu'ils apprennent la conséquences d'une mauvaise conception et d'une mauvaise programmation, et ils redouteront de voir leur propre code publié sur The Daily WTF .

6
jqa

Un principe qui n'a pas été mentionné mais que je trouve important est le principe ouvert/fermé .

Vous ne devez pas modifier le code qui a été développé et testé: un tel morceau de code est scellé. Au lieu de cela, étendez les classes existantes au moyen de sous-classes, ou utilisez-les en écrivant des wrappers, des classes décorateur ou en utilisant le modèle que vous trouvez approprié. Mais ne change pas le code de travail .

Juste mes 2 cents.

5
Giorgio
  • Soyez un éclaireur . Laissez toujours le code plus propre que vous ne l'avez trouvé.

  • Corrigez le fenêtres cassées . Tous ces commentaires "changent dans la version 2.0" lorsque vous êtes sur la version 3.0.

  • Lorsqu'il y a des hacks majeurs, concevez une meilleure solution en équipe et faites-le. Si vous ne pouvez pas résoudre le piratage en équipe, vous ne comprenez pas assez bien le système. "Demandez de l'aide à un adulte." Les personnes les plus âgées autour auraient peut-être déjà vu cela auparavant. Essayez de dessiner ou d'extraire un diagramme du système. Essayez de dessiner ou d'extraire les cas d'utilisation qui sont particulièrement hacky en tant que diagrammes d'interaction. Cela ne le résout pas, mais au moins vous pouvez le voir.

  • Quelles hypothèses ne sont plus vraies qui ont poussé la conception dans une direction particulière? Il pourrait y avoir un petit refactoring se cachant derrière une partie de ce gâchis.

  • Si vous expliquez le fonctionnement du système (ne serait-ce qu'un seul cas d'utilisation) et que vous devez vous excuser à maintes reprises pour un sous-système, c'est le problème. Quel comportement simplifierait le reste du système (quelle que soit la difficulté à mettre en œuvre par rapport à ce qui existe). Le sous-système classique à réécrire est celui qui pollue tous les autres sous-systèmes avec sa sémantique de fonctionnement et son implémentation. "Oh, vous devez grozer les valeurs avant de les introduire dans le sous-système froo, puis les dés-grozer à nouveau lorsque vous obtenez la sortie de la froo. et le reste du système est faux? Cela devient plus excitant quand il y a deux ou plusieurs grozifications différentes.

  • Passez une semaine en équipe à supprimer les avertissements afin que les vrais problèmes soient visibles.

  • Reformatez tout le code selon la norme de codage.

  • Assurez-vous que votre système de contrôle de version est lié à votre traqueur de bogues. Cela signifie que les changements futurs sont agréables et responsables, et vous pouvez déterminer POURQUOI.

  • Faites de l'archéologie. Trouvez les documents de conception originaux et examinez-les. Ils pourraient être sur ce vieux PC dans le coin du bureau, dans l'espace de bureau abandonné ou dans le classeur que personne n'ouvre jamais.

  • Republiez les documents de conception sur un wiki. Cela aide à institutionnaliser les connaissances.

  • Rédiger des procédures de liste de contrôle pour les versions et les builds. Cela empêche les gens de réfléchir, afin qu'ils puissent se concentrer sur la résolution des problèmes. Automatisez les versions autant que possible.

  • Essayez intégration continue . Plus tôt vous obtenez un build échoué, moins le projet peut passer de temps sur les Rails.

  • Si votre chef d'équipe ne fait pas ces choses, c'est mauvais pour l'entreprise.

  • Essayez de vous assurer que tout nouveau code obtient des tests unitaires appropriés avec une couverture mesurée. Le problème ne peut donc pas empirer.

  • Essayez de tester un peu certains des anciens bits qui ne sont pas testés unitaire. Cela aide à réduire la peur du changement.

  • Automatisez votre test d'intégration et de régression si vous le pouvez. Ayez au moins une liste de contrôle. Les pilotes sont intelligents et reçoivent des lots payés et ils utilisent des listes de contrôle. Ils bousillent aussi assez rarement.

5
Tim Williscroft

Lisez puis relisez Code Complete par Steve McConnell. C'est comme une bible de bonne écriture logicielle, de la conception initiale du projet à une seule ligne de code et tout le reste. Ce que j'aime le plus, c'est qu'il est soutenu par des décennies de données solides; ce n'est pas seulement le meilleur style de codage suivant.

4
dwenaus

Je suis venu pour appeler cela "l'effet Winchester Mystery House". Comme la maison, cela a commencé assez simplement, mais au fil des ans, de nombreux travailleurs différents ont ajouté tellement de fonctionnalités étranges sans plan global que personne ne le comprend vraiment. Pourquoi cet escalier ne va-t-il nulle part et pourquoi cette porte ne s'ouvre-t-elle que dans un sens? Qui sait?

La façon de limiter cet effet est de commencer par une bonne conception faite là où elle est suffisamment flexible pour gérer l'expansion. Plusieurs suggestions ont déjà été faites à ce sujet.

Mais, souvent, vous prendrez un travail où les dommages ont déjà été causés et il est trop tard pour une bonne conception sans effectuer une refonte et une réécriture coûteuses et potentiellement risquées. Dans ces situations, il est préférable d'essayer de trouver des moyens de limiter le chaos tout en l'embrassant dans une certaine mesure. Cela peut ennuyer vos sensibilités de conception selon lesquelles tout doit passer par une énorme classe de `` gestionnaire '' laide et laide ou la couche d'accès aux données est étroitement couplée à l'interface utilisateur, mais apprenez à y faire face. Codez défensivement dans ce cadre et essayez de vous attendre à l'inattendu lorsque des "fantômes" de programmeurs passés apparaissent.

3
jfrankcarr

Je veux juste placer un problème non technique et une approche (peut-être) pragmatique.

Si votre responsable ne se soucie pas de la qualité technique (code gérable, architecture simple, infrastructure fiable, etc.), il devient difficile d'améliorer le projet. Dans ce cas, il est nécessaire d'éduquer ledit manager et de convaincre "d'investir" dans maintenabilité et de traiter dette technique .

Si vous rêvez de la qualité du code trouvée dans ces livres, vous avez également besoin d'un patron qui s'en préoccupe.

Ou si vous voulez juste apprivoiser un "projet Frankenstein", voici mes conseils:

  • Organisez et simplifiez
  • Raccourcir les fonctions
  • Privilégiez la lisibilité à l'efficacité (lorsque cela est acceptable bien sûr, et certains gains d'efficacité sont trop misérables pour être conservés)

D'après mon expérience, la programmation est entropique plutôt qu'émergente (du moins dans le paradigme populaire à structure impérative). Lorsque les gens écrivent du code pour "simplement travailler", la tendance est de perdre son organisation. Or, organiser du code demande du temps, parfois bien plus que de le faire fonctionner.

Au-delà de l'implémentation des fonctionnalités et des corrections de bugs, prenez votre temps pour le nettoyage du code.

2
Eric.Void

Refactoring de code et tests unitaires sont parfaitement bien. Mais comme ce projet de longue haleine se heurte à des hacks, cela signifie que la direction ne met pas le pied à terre pour nettoyer la pourriture. L'équipe doit introduire des hacks, car quelqu'un n'alloue pas suffisamment de ressources pour former les gens et analyser le problème/la demande.

Le maintien d'un projet de longue durée est autant une responsabilité du chef de projet qu'un développeur individuel.

Les gens n'introduisent pas de hacks parce qu'ils aiment ça; ils sont forcés par les circonstances.

2
ViSu

J'ai été surpris de constater qu'aucune des nombreuses réponses ne mettait en évidence l'évidence: faire en sorte que le logiciel se compose de nombreuses petites bibliothèques indépendantes. Avec de nombreuses petites bibliothèques, vous pouvez construire un logiciel gros et complexe. Si les exigences changent, vous n'avez pas à jeter l'intégralité de la base de code ni à rechercher comment modifier une grande base de code de klaxon pour faire autre chose que ce qu'elle fait actuellement. Vous décidez simplement lesquelles de ces bibliothèques sont toujours pertinentes après que les exigences changent et comment les combiner pour avoir la nouvelle fonctionnalité.

Utilisez toutes les techniques de programmation dans les bibliothèques qui facilitent l'utilisation de la bibliothèque. Notez que par ex. tout langage non orienté objet prenant en charge les pointeurs de fonction prend en charge la programmation orientée objet (POO). Ainsi, par exemple en C, vous pouvez faire de la POO.

Vous pouvez même envisager de partager ces petites bibliothèques indépendantes entre plusieurs projets (les sous-modules git sont vos amis).

Il va sans dire que chaque petite bibliothèque indépendante doit être testée à l'unité. Si une bibliothèque particulière n'est pas testable à l'unité, vous faites quelque chose de mal.

Si vous utilisez C ou C++ et que vous n'aimez pas l'idée d'avoir de nombreux petits fichiers .so, vous pouvez lier toutes les bibliothèques ensemble dans un fichier .so plus grand, ou bien vous pouvez faire une liaison statique. La même chose est vraie pour Java, changez simplement .so en .jar.

1
juhist

Simple: réduisez les coûts de maintenance de la plupart de votre code à zéro jusqu'à ce que vous ayez un nombre maintenable de pièces mobiles. Un code qui n'a jamais besoin d'être modifié n'entraîne aucun coût de maintenance. Je recommande de viser à ce que le code ait vraiment zéro coût de maintenance, sans essayer de réduire le coût sur de nombreuses itérations de refactorisation petites et difficiles. Faites-en un coût zéro tout de suite.

D'accord, c'est beaucoup, beaucoup plus difficile qu'il n'y paraît. Mais ce n'est pas difficile de commencer. Vous pouvez prendre une partie de la base de code, la tester, construire une belle interface dessus si la conception de l'interface est un gâchis et commencer à agrandir les parties de la base de code qui sont fiables, stables (comme en l'absence de raisons de changer), tout en simultanément rétrécir les parties qui ne sont pas fiables et instables. Les bases de code qui ressemblent à un cauchemar à entretenir ne distinguent souvent pas les pièces mobiles qui doivent être changées des pièces qui ne le sont pas, car tout est jugé peu fiable et susceptible de changer.

Je recommande en fait de séparer l'organisation de votre base de code en parties "stables" et "instables", les parties stables étant un énorme PITA à reconstruire et à modifier (ce qui est une bonne chose, car elles ne devraient pas avoir besoin de être modifiés et reconstruits s'ils appartiennent vraiment à la section "stable").

Ce n'est pas la taille d'une base de code qui rend la maintenabilité difficile. C'est la taille de la base de code qui doit être maintenue. Je dépends de millions de lignes de code chaque fois que j'utilise, par exemple, l'API du système d'exploitation. Mais cela ne contribue pas aux coûts de maintenance de mon produit, car je n'ai pas à maintenir le code source du système d'exploitation. J'utilise juste le code et ça marche. Le code que j'utilise simplement et que je n'ai jamais à entretenir n'engendre aucun frais de maintenance de ma part.

0
user204677