web-dev-qa-db-fra.com

J'ai hérité de 200K lignes de code spaghetti - et maintenant?

J'espère que ce n'est pas trop général d'une question; Je pourrais vraiment utiliser des conseils chevronnés.

Je suis nouvellement employé en tant que seul "ingénieur SW" dans un assez petit magasin de scientifiques qui ont passé les 10 à 20 dernières années à bricoler une vaste base de codes. (Il a été écrit dans un langage pratiquement obsolète: G2 - pensez Pascal avec les graphiques). Le programme lui-même est un modèle physique d'une usine de traitement chimique complexe; l'équipe qui l'a écrit possède une connaissance du domaine incroyablement profonde, mais peu ou pas de formation formelle dans les principes de programmation. Ils ont récemment appris des leçons difficiles sur les conséquences d'une gestion de configuration inexistante. Leurs efforts de maintenance sont également considérablement entravés par la vaste accumulation de "boues" non documentées dans le code lui-même. Je vous épargnerai la "politique" de la situation (il y a toujours politique!), Mais il suffit de dire qu'il n'y a pas de consensus sur ce que est nécessaire pour la voie à suivre.

Ils m'ont demandé de commencer à présenter à l'équipe certains des principes du développement logiciel moderne. Ils veulent que je présente certaines des pratiques et stratégies standard de l'industrie concernant les conventions de codage, la gestion du cycle de vie, les modèles de conception de haut niveau et le contrôle des sources. Franchement, c'est une tâche assez ardue et je ne sais pas par où commencer.

Au départ, je suis enclin à les enseigner dans certains des concepts centraux de Le programmeur pragmatique , ou Fowler's Refactoring ("Code Odeurs", etc.). J'espère également présenter un certain nombre de méthodologies Agiles. Mais en fin de compte, pour être efficace, je pense que je vais devoir me concentrer sur 5-7 fondamentaux fondamentaux; en d'autres termes, quels sont les principes ou pratiques les plus importants qu'ils peuvent commencer à mettre en œuvre de manière réaliste et qui leur en donneront le plus pour leur argent.

Voilà ma question: qu'est-ce que vous incluriez dans votre liste des stratégies les plus efficaces pour aider à redresser les spaghettis (et à les empêcher à l'avenir)?

468
kmote

Préface

Il s'agit en effet d'une tâche ardue et il y a beaucoup de chemin à parcourir. Je propose donc humblement ce guide quelque peu complet pour votre équipe, avec des pointeurs vers des outils appropriés et du matériel éducatif.

N'oubliez pas: Ce sont des directives, et qui en tant que telles sont destinées à être adoptées, adaptées ou abandonnées en fonction des circonstances.

Méfiez-vous: Vider tout cela sur une équipe à la fois échouerait très probablement. Vous devriez essayer de choisir les éléments qui vous donneraient le meilleur coup de sueur et de les introduire lentement, un à la fois.

Remarque: tout cela ne s'applique pas directement aux systèmes de programmation visuels comme G2. Pour plus de détails sur la façon de les gérer, consultez la section Addendum à la fin.


Résumé pour les impatients

  • Définissez une structure de projet rigide, avec:
    • modèles de projets,
    • conventions de codage,
    • systèmes familiers build,
    • et des ensembles de consignes d'utilisation pour votre infrastructure et vos outils.
  • Installez une bonne SCM et assurez-vous qu'ils savent comment l'utiliser.
  • Dirigez-les vers de bons IDE pour leur technologie et assurez-vous qu'ils savent comment les utiliser.
  • Implémentez des vérificateurs de qualité code et automatique dans le système de génération.
  • Associez le système de construction aux systèmes d'intégration continue et d'inspection continue.
  • À l'aide de ce qui précède, identifiez les "points d'accès" de qualité code et refactor.

Maintenant pour la version longue ... Attention, accrochez-vous !


La rigidité est (souvent) bonne

Ceci est une opinion controversée, car la rigidité est souvent considérée comme une force qui travaille contre vous. C'est vrai pour certaines phases de certains projets. Mais une fois que vous le voyez comme un support structurel, un cadre qui élimine les conjectures, il réduit considérablement la quantité de temps et d'efforts perdus. Faites-le fonctionner pour vous, pas contre vous.

Rigidité = Processus/ Procédure.

Le développement de logiciels nécessite de bons processus et procédures pour les mêmes raisons que les usines ou usines chimiques ont des manuels, des procédures, des exercices et des directives d'urgence: prévenir les mauvais résultats, augmenter la prévisibilité, maximiser la productivité ...

La rigidité est cependant modérée!

Rigidité de la structure du projet

Si chaque projet est livré avec sa propre structure, vous (et les nouveaux arrivants) êtes perdus et devez reprendre à zéro chaque fois que vous les ouvrez. Vous ne voulez pas cela dans un magasin de logiciels professionnel, et vous ne voulez pas non plus cela dans un laboratoire.

Rigidité des systèmes de construction

Si chaque projet semble différent, il y a de fortes chances qu'ils construisent différemment. Une construction ne devrait pas nécessiter trop de recherches ou trop de conjectures. Vous voulez pouvoir faire la chose canonique et ne pas avoir à vous soucier des détails: configure; make install, ant, mvn install, etc...

Réutiliser le même système de construction et le faire évoluer dans le temps garantit également un niveau de qualité constant.

Vous avez besoin d'un README rapide pour pointer les détails du projet et guider gracieusement l'utilisateur/développeur/chercheur, le cas échéant.

Cela facilite également grandement d'autres parties de votre infrastructure de construction, à savoir:

Gardez donc votre build (comme vos projets) à jour, mais rendez-le plus strict au fil du temps et plus efficace pour signaler les violations et les mauvaises pratiques.

Ne réinventez pas la roue et réutilisez ce que vous avez déjà fait.

Lecture recommandée:

Rigidité dans le choix des langages de programmation

Vous ne pouvez pas vous attendre, en particulier dans un environnement de recherche, à ce que toutes les équipes (et encore moins tous les développeurs) utilisent la même pile de langage et de technologie. Cependant, vous pouvez identifier un ensemble d'outils "officiellement pris en charge" et encourager leur utilisation. Le reste, sans une bonne justification, ne devrait pas être autorisé (au-delà du prototypage).

Gardez votre pile technologique simple et le maintien et l'étendue des compétences requises au strict minimum: un noyau solide.

Rigidité des conventions et directives de codage

Les conventions de codage et les lignes directrices sont ce qui vous permet de développer à la fois une identité d'équipe et un partage lingo. Vous ne voulez pas vous tromper dans terra incognita chaque fois que vous ouvrez un fichier source.

Les règles absurdes qui rendent la vie plus difficile ou interdisent explicitement les actions dans la mesure où les commits sont refusés sur la base de simples violations simples sont un fardeau. Toutefois:

  • un ensemble de règles de base bien pensé enlève beaucoup de pleurnicheries et de réflexion: personne ne devrait rompre en aucun cas;

  • et un ensemble de règles recommandées fournissent des indications supplémentaires.

Approche personnelle: Je suis agressif en ce qui concerne les conventions de codage, certains disent même nazi, parce que je crois avoir un lingua franca, un style reconnaissable pour mon équipe. Lorsque le code de merde est enregistré, il se démarque comme un bouton de fièvre sur le visage d'une star hollywoodienne: il déclenche automatiquement un examen et une action. En fait, je suis parfois allé jusqu'à préconiser l'utilisation de hooks de pré-validation pour rejeter les validations non conformes. Comme mentionné, il ne devrait pas être trop fou et nuire à la productivité: il devrait le conduire. Présentez-les lentement, surtout au début. Mais il est préférable de passer autant de temps à réparer le code défectueux que vous ne pouvez pas travailler sur de vrais problèmes.

Certaines langues appliquent même cela par conception:

  • Java était censé réduire la quantité de conneries ennuyeuses que vous pouvez écrire avec (bien que beaucoup parviennent sans aucun doute à le faire).
  • La structure de blocs de Python par indentation est une autre idée dans ce sens.

  • Allez, avec son outil gofmt, qui enlève complètement tout débat et effort (et ego !!) inhérents au style: exécutez gofmt avant de vous engager.

Assurez-vous que code rot ne peut pas passer. Les conventions Code, intégration continue et inspection continue, la programmation paire et les revues code sont votre arsenal contre ce démon.

De plus, comme vous le verrez ci-dessous, code est la documentation, et c'est un autre domaine où les conventions encouragent la lisibilité et la clarté.

Rigidité de la documentation

La documentation va de pair avec le code. Le code lui-même est de la documentation. Mais il doit y avoir des instructions claires sur la façon de construire, d'utiliser et d'entretenir les choses.

L'utilisation d'un seul point de contrôle pour la documentation (comme un WikiWiki ou DMS) est une bonne chose. Créez des espaces pour les projets, des espaces pour des plaisanteries plus aléatoires et des expériences Demandez à tous les espaces de réutiliser des règles et des conventions communes. Essayez de l'intégrer à l'esprit d'équipe.

La plupart des conseils concernant le code et les outils s'appliquent également à la documentation.

Rigidité dans les commentaires du code

Les commentaires de code, comme mentionné ci-dessus, sont également de la documentation. Les développeurs aiment exprimer leurs sentiments à propos de leur code (principalement la fierté et la frustration, si vous me le demandez). Il n'est donc pas inhabituel pour eux de les exprimer en termes non incertains dans des commentaires (ou même du code), alors qu'un morceau de texte plus formel aurait pu transmettre la même signification avec moins d'expressions ou de drames. Il est permis d'en laisser quelques-uns passer pour des raisons amusantes et historiques: cela fait également partie de développer une culture d'équipe. Mais il est très important que tout le monde sache ce qui est acceptable et ce qui ne l'est pas, et ce bruit de commentaire n'est que cela: noise.

Rigidité dans les journaux de validation

Les journaux de validation ne sont pas une "étape" gênante et inutile du cycle de vie de votre SCM: vous NE LE sautez PAS pour rentrer à temps à la maison ou passer à la tâche suivante, ou pour rattraper les copains qui sont partis pour le déjeuner. Ils sont importants et, comme (la plupart) du bon vin, plus le temps passe, plus ils deviennent précieux. Alors, faites-les bien. Je suis sidéré quand je vois des collègues écrire des lignes simples pour des commits géants ou pour des hacks non évidents.

Les validations sont effectuées pour une raison, et cette raison N'EST PAS toujours clairement exprimée par votre code et la ligne de journal de validation que vous avez saisie. Il y a plus que ça.

Chaque ligne de code a un story, et un history. Les diffs peuvent raconter son histoire, mais il faut écrire son histoire.

Pourquoi ai-je mis à jour cette ligne? -> Parce que l'interface a changé.

Pourquoi l'interface a-t-elle changé? -> Parce que la bibliothèque L1 le définissant a été mise à jour.

Pourquoi la bibliothèque a-t-elle été mise à jour? -> Parce que la bibliothèque L2, dont nous avons besoin pour la fonctionnalité F, dépendait de la bibliothèque L1.

Et quelle est la fonctionnalité X? -> Voir la tâche 3456 dans le suivi des problèmes.

Ce n'est pas mon choix SCM, et ce n'est peut-être pas le meilleur pour votre laboratoire non plus; mais Git obtient ce droit et essaie de vous forcer à écrire de bons journaux plus que la plupart des autres systèmes SCM, en utilisant short logs et long logs. Liez l'ID de tâche (oui, vous en avez besoin) et laissez un résumé générique pour le shortlog, et développez dans le journal long: écrivez le story du jeu de modifications.

C'est un journal: Il est là pour garder une trace et enregistrer les mises à jour.

Règle générale: Si vous cherchiez quelque chose à propos de ce changement plus tard, votre journal est-il susceptible de répondre à votre question?

Les projets, la documentation et le code sont VIVANTS

Gardez-les synchronisés, sinon ils ne forment plus cette entité symbiotique. Cela fait des merveilles lorsque vous avez:

  • effacer les journaux de validation dans votre SCM, avec des liens vers les ID de tâche dans votre outil de suivi des problèmes,
  • où les tickets de ce tracker sont eux-mêmes liés aux changesets de votre SCM (et éventuellement aux builds de votre système CI),
  • et un système de documentation qui relie à tout cela.

Le code et la documentation doivent être cohérents.

Rigidité dans les tests

Règles de base:

  • Tout nouveau code doit être accompagné (au moins) de tests unitaires.
  • Tout code hérité remanié doit être accompagné de tests unitaires.

Bien sûr, ceux-ci ont besoin:

  • pour tester réellement quelque chose de précieux (ou ils sont une perte de temps et d'énergie),
  • être bien écrit et commenté (comme tout autre code que vous enregistrez).

Ils sont également de la documentation et ils aident à définir le contrat de votre code. Surtout si vous utilisez TDD . Même si vous n'en avez pas, vous en avez besoin pour votre tranquillité d'esprit. Ils sont votre filet de sécurité lorsque vous incorporez un nouveau code (maintenance ou fonctionnalité) et votre tour de guet pour vous prémunir contre la pourriture du code et les défaillances environnementales.

Bien sûr, vous devriez aller plus loin et avoir tests d'intégration , et tests de régression pour chaque bogue reproductible que vous corrigez.

Rigidité dans l'utilisation des outils

Il est normal que le développeur/scientifique occasionnel veuille essayer un nouveau vérificateur statique sur la source, générer un graphique ou un modèle en utilisant un autre, ou implémenter un nouveau module en utilisant un DSL. Mais il est préférable qu'il existe un ensemble canonique d'outils que les membres de l'équipe all sont censés connaître et utiliser.

Au-delà de cela, laissez les membres utiliser ce qu'ils veulent, tant qu'ils sont TOUS:

  • productif,
  • N'ayant PAS régulièrement besoin d'aide
  • PAS s'adapter régulièrement à votre infrastructure générale,
  • NE PAS perturber votre infrastructure (en modifiant les parties communes comme le code, le système de build, la documentation ...),
  • N'affectant PAS le travail des autres,
  • CAPABLE d'exécuter en temps opportun toute tâche demandée.

Si ce n'est pas le cas, assurez-vous qu'ils retombent aux valeurs par défaut.


Rigidité vs polyvalence, adaptabilité, prototypage et urgences

La flexibilité peut être bonne. Laisser quelqu'un utiliser occasionnellement un hack, une approche rapide et un outil favori pour faire le travail est très bien. N'A JAMAIS laisser cela devenir une habitude, et N'A JAMAIS que ce code devienne la base de code réelle à prendre en charge.


L'esprit d'équipe est important

Développez un sentiment de fierté dans votre base de code

  • Développer un sentiment de fierté dans le code
    • Utilisez des panneaux muraux
      • tableau des leaders pour un jeu d'intégration continue
      • panneaux muraux pour la gestion des problèmes et le comptage des défauts
    • Utilisez un problème tracker / bug tracker

Évitez les jeux de blâme

  • UTILISEZ des jeux d'intégration continue/d'inspection continue: cela encourage les bonnes manières et compétition productive .
  • SUIVEZ LES DÉFAUTS: c'est juste un bon ménage.
  • FAIRE identifier les causes profondes: ce ne sont que des processus évolutifs.
  • MAIS NE PAS blâmer : c'est contre-productif.

Il s'agit du code, pas des développeurs

Rendre les développeurs conscients de la qualité de leur code, MAIS leur faire voir le code comme une entité détachée et non comme une extension d'eux-mêmes, ce qui ne peut être critiqué.

C'est un paradoxe: vous devez encourager programmation sans ego pour un lieu de travail sain, mais compter sur l'ego à des fins de motivation.


Du scientifique au programmeur

Les gens qui ne valorisent pas et ne sont pas fiers du code ne produisent pas un bon code. Pour que cette propriété émerge, ils doivent découvrir à quel point elle peut être précieuse et amusante. Le simple professionnalisme et l'envie de faire le bien ne suffisent pas: il faut de la passion. Vous devez donc transformer vos scientifiques en programmeurs (au sens large).

Quelqu'un a fait valoir dans les commentaires qu'après 10 à 20 ans sur un projet et son code, n'importe qui se sentirait attaché. Peut-être que je me trompe, mais je suppose qu'ils sont fiers des résultats du code et du travail et de son héritage, pas du code lui-même ou de l'acte de l'écrire.

Par expérience, la plupart des chercheurs considèrent le codage comme une nécessité, ou au mieux comme une distraction amusante. Ils veulent juste que ça marche. Ceux qui s'y connaissent déjà assez bien et qui s'intéressent à la programmation sont beaucoup plus faciles à persuader d'adopter les meilleures pratiques et les technologies de commutation. Vous devez les amener à mi-chemin.


La maintenance du code fait partie des travaux de recherche

Personne ne lit les articles de recherche pourris. C'est pourquoi ils sont révisés par des pairs, relus, affinés, réécrits et approuvés à maintes reprises jusqu'à ce qu'ils soient jugés prêts pour la publication. Il en va de même pour une thèse et une base de code!

Expliquez clairement que le refactoring et l'actualisation constants d'une base de code empêchent la pourriture du code et réduisent la dette technique, et facilitent la réutilisation et l'adaptation futures du travail pour d'autres projets.


Pourquoi tout ça??!

Pourquoi nous dérange-t-on avec tout ce qui précède? Pour la qualité code. Ou est-ce code de qualité ...?

Ces directives visent à conduire votre équipe vers cet objectif. Certains aspects le font simplement en leur montrant le chemin et en les laissant le faire (ce qui est beaucoup mieux) et d'autres les prennent par la main (mais c'est ainsi que vous éduquez les gens et développez des habitudes).

Comment savez-vous que l'objectif est à portée de main?

La qualité est mesurable

Pas toujours quantitativement, mais c'est est mesurable. Comme mentionné, vous devez développer un sentiment de fierté envers votre équipe, et montrer les progrès et les bons résultats est la clé. Mesurez régulièrement la qualité du code et montrez la progression entre les intervalles et son importance. Faites des rétrospectives pour réfléchir à ce qui a été fait et comment cela a amélioré ou aggravé les choses.

Il existe d'excellents outils pour inspection continue. Sonar étant populaire dans le monde Java, mais il peut s'adapter à toutes les technologies; et il y en a beaucoup d'autres. Gardez votre code sous le microscope et recherchez-les insectes et microbes ennuyeux embêtants.


Mais que faire si mon code est déjà merdique?

Tout ce qui précède est amusant et mignon comme un voyage à Never Land, mais ce n'est pas si facile à faire quand vous avez déjà (un tas de code de merde torride et malodorante) et une équipe réticente à changer.

Voici le secret: vous devez commencer quelque part.

Anecdote personnelle: Dans un projet, nous avons travaillé avec une base de code pesant à l'origine 650 000+ Java LOC, 200 000+ lignes de JSP, 40 000+ JavaScript LOC et 400+ Mo de dépendances binaires .

Après environ 18 mois, c'est 500 000 Java LOC (MOSTLY CLEAN), 150 000 lignes de JSP et 38 000 LOC JavaScript, avec des dépendances jusqu'à à peine 100 Mo (et ce ne sont pas dans notre SCM plus!).

Comment avons-nous fait ça? Nous venons de faire tout ce qui précède. Ou bien essayé.

C'est un effort d'équipe, mais nous injectons lentement dans nos réglementations de processus et des outils pour surveiller la fréquence cardiaque de notre produit, tout en réduisant à la hâte le "gras": code de merde, dépendances inutiles ... Nous n'avons pas arrêté tout développement pour le faire: nous avons parfois des périodes de paix relative et de calme où nous sommes libres de devenir fous de la base de code et de le déchirer, mais la plupart du temps, nous faisons tout cela par défaut à un "examen et refactoriser "chaque chance que nous obtenons: pendant les builds, pendant le déjeuner, pendant les sprints de correction de bugs, les vendredis après-midi ...

Il y a eu de gros "travaux" ... Le passage de notre système de construction d'une génération Ant gigantesque de 8500+ XML LOC à une construction Maven multi-modules en faisait partie. Nous avons ensuite eu:

  • modules clairs (ou du moins c'était déjà beaucoup mieux, et nous avons encore de grands projets pour l'avenir),
  • gestion automatique des dépendances (pour une maintenance et des mises à jour faciles, et pour supprimer les dépôts inutiles),
  • constructions plus rapides, plus faciles et reproductibles,
  • rapports quotidiens sur la qualité.

Un autre a été l'injection de "ceintures à outils utilitaires", même si nous essayions de réduire les dépendances: Google Guava et Apache Commons réduisent votre code et réduisent beaucoup la surface des bogues dans le code votre.

Nous avons également convaincu notre service informatique que l'utilisation de nos nouveaux outils (JIRA, Fisheye, Crucible, Confluence, Jenkins) était peut-être meilleure que celles en place. Nous devions encore faire face à certains que nous méprisions (QC, Sharepoint et SupportWorks ...), mais ce fut une expérience globale améliorée, avec encore plus de place.

Et chaque jour, il y a maintenant un filet entre une à des dizaines de commits qui ne concernent que la correction et la refactorisation de choses. Nous cassons occasionnellement des trucs (vous avez besoin de tests unitaires, et vous feriez mieux de les écrire avant de refactoriser les trucs), mais dans l'ensemble, l'avantage pour notre moral ET pour le produit a été énorme. Nous obtenons une fraction d'un pourcentage de qualité du code à la fois. Et c'est amusant de le voir augmenter !!!

Remarque: Encore une fois, la rigidité doit être ébranlée pour faire de la place à de nouvelles et meilleures choses. Dans mon anecdote, notre service informatique a en partie raison d'essayer de nous imposer certaines choses, et tort pour d'autres. Ou peut-être qu'ils avaient raison. Les choses changent. Prouvez qu'ils sont de meilleurs moyens d'augmenter votre productivité. Les essais et les prototypes sont là pour ça.


Le cycle de refactorisation incrémental du code spaghetti super secret pour une qualité impressionnante

       +-----------------+      +-----------------+
       |  A N A L Y Z E  +----->| I D E N T I F Y |
       +-----------------+      +---------+-------+
                ^                           |
                |                           v
       +--------+--------+      +-----------------+
       |    C L E A N    +<-----|      F I X      |
       +-----------------+      +-----------------+

Une fois que vous avez des outils de qualité à votre ceinture:

  1. Analysez votre code avec des vérificateurs de qualité de code.

    Linters, analyseurs statiques, etc.

  2. Identifiez vos hotspots critiques ET les fruits à faible pendaison.

    Les violations ont des niveaux de gravité, et les grandes classes avec un grand nombre de celles à gravité élevée sont un gros drapeau rouge: en tant que telles, elles apparaissent comme des "points chauds" sur les types de vues radiateur/carte thermique.

  3. Réparez les hotspots en premier.

    Il maximise votre impact dans un court laps de temps car ils ont la valeur commerciale la plus élevée. Idéalement, les violations critiques devraient être traitées dès leur apparition, car ce sont des failles de sécurité potentielles ou des causes de crash, et présentent un risque élevé d'induire une responsabilité (et dans votre cas, de mauvaises performances pour le laboratoire).

  4. Nettoyez les violations de bas niveau avec des balayages de base de code automatisés.

    Il améliore le rapport signal/bruit afin que vous puissiez voir les violations importantes sur votre radar à mesure qu'elles apparaissent. Il y a souvent une grande armée de violations mineures au début si elles n'ont jamais été prises en charge et que votre base de code a été laissée libre dans la nature. Ils ne présentent pas de réel "risque", mais ils nuisent à la lisibilité et à la maintenabilité du code. Corrigez-les soit lorsque vous les rencontrez tout en travaillant sur une tâche, soit par de grandes quêtes de nettoyage avec des balayages de code automatisés si possible. Soyez prudent avec les grands balayages automatiques si vous n'avez pas une bonne suite de tests et un bon système d'intégration. Assurez-vous de convenir avec vos collègues du bon moment pour les exécuter afin de minimiser la gêne.

  5. Répétez jusqu'à ce que vous soyez satisfait.

    Ce qui, idéalement, ne devrait jamais l'être, s'il s'agit toujours d'un produit actif: il continuera d'évoluer.

Conseils rapides pour une bonne gestion de la maison

  • En mode hotfix, sur la base d'une demande d'assistance client:

    • Il est généralement recommandé de NE PAS contourner d'autres problèmes, car vous pourriez en introduire de nouveaux à contrecœur.
    • Allez-y style SEAL: entrez, tuez le bug, sortez et expédiez votre patch. C'est une frappe chirurgicale et tactique.
  • Mais pour tous les autres cas, si vous ouvrez un fichier, faites-vous votre devoir de:

    • certainement:revoir (prendre des notes, signaler les problèmes de fichiers),
    • peut-être:clean it (nettoyages de style et violations mineures),
    • idéalement:refactoriser (réorganiser les grandes sections et leurs voisins).

Ne vous laissez pas distraire par passer une semaine d'un fichier à l'autre et vous retrouver avec un ensemble de modifications massives de milliers de correctifs couvrant plusieurs fonctionnalités et modules - cela rend le suivi futur difficile. Un problème de code = un ticket dans votre tracker. Parfois, un ensemble de modifications peut affecter plusieurs tickets; mais si cela arrive trop souvent, vous faites probablement quelque chose de mal.


Addendum: Gestion des environnements de programmation visuels

Les jardins clos des systèmes de programmation sur mesure

Plusieurs systèmes de programmation, comme l'OP G2, sont des bêtes différentes ...

  • Pas de "code" source

    Souvent, ils ne vous donnent pas accès à une représentation textuelle de votre "code" source: il peut être stocké dans un format binaire propriétaire, ou peut-être qu'il stocke des choses au format texte mais les cache loin de vous. Les systèmes de programmation graphique sur mesure ne sont en fait pas rares dans les laboratoires de recherche, car ils simplifient l'automatisation des workflows de traitement de données répétitifs.

  • Aucun outillage

    Mis à part le leur, c'est. Vous êtes souvent contraint par leur environnement de programmation, leur propre débogueur, leur propre interprète, leurs propres outils et formats de documentation. Ce sont des jardins murés, sauf s'ils finissent par susciter l'intérêt de quelqu'un suffisamment motivé pour faire de l'ingénierie inverse de leurs formats et créer des outils externes - si la licence le permet.

  • Manque de documentation

    Il s'agit assez souvent de systèmes de programmation de niche, qui sont utilisés dans des environnements assez fermés. Les personnes qui les utilisent signent fréquemment des NDA et ne parlent jamais de ce qu'ils font. Les communautés de programmation pour eux sont rares. Les ressources sont donc rares. Vous êtes coincé avec votre référence officielle, et c'est tout.

L'ironie (et souvent la frustration) est que tout ce que font ces systèmes pourrait évidemment être réalisé en utilisant des langages de programmation à usage général et général, et probablement plus efficacement. Mais cela nécessite une connaissance plus approfondie de la programmation, alors que vous ne pouvez pas vous attendre à ce que votre biologiste, chimiste ou physicien (pour n'en nommer que quelques-uns) en sache assez sur la programmation, et encore moins à avoir le temps (et le désir) de mettre en œuvre (et de maintenir) systèmes complexes, qui peuvent ou non durer longtemps. Pour la même raison que nous utilisons les DSL, nous avons ces systèmes de programmation sur mesure.

Anecdote personnelle 2: En fait, j'ai moi-même travaillé sur l'un d'eux. Je n'ai pas fait le lien avec la demande du PO, mais mon projet était un ensemble de gros logiciels de traitement et de stockage de données interconnectés (principalement pour la recherche en bio-informatique, les soins de santé et les cosmétiques, mais aussi pour les entreprises) intelligence ou tout domaine impliquant le suivi de gros volumes de données de recherche de toute nature et la préparation de workflows informatiques et ETL). L'une de ces applications était, tout simplement, un visuel IDE qui utilisait les cloches et les sifflets habituels: interfaces de glisser-déposer, espaces de travail de projet versionnés (en utilisant des fichiers texte et XML pour le stockage des métadonnées), beaucoup de des pilotes enfichables vers des sources de données hétérogènes et un canevas visuel pour concevoir des pipelines pour traiter les données à partir de N sources de données et générer à la fin M sorties transformées, et des visualisations brillantes possibles et des rapports en ligne complexes (et interactifs). Votre système de programmation visuel sur mesure typique, souffrant de un peu de syndrome NIH sous prétexte de concevoir un système adapté aux besoins des utilisateurs.

Et, comme vous vous en doutez, c'est un système sympa, assez flexible pour ses besoins bien que parfois un peu exagéré de sorte que vous vous demandez "pourquoi ne pas utiliser des outils de ligne de commande à la place?", Et malheureusement toujours en tête de taille moyenne des équipes travaillant sur de grands projets à un grand nombre de personnes différentes qui l'utilisent avec différentes "meilleures" pratiques.

Super, nous sommes condamnés! - Que faisons-nous à propos de cela?

Eh bien, à la fin, tout ce qui précède tient toujours. Si vous ne pouvez pas extraire la majeure partie de la programmation de ce système pour utiliser des outils et des langages plus courants, il vous suffit "de" l'adapter aux contraintes de votre système.

À propos du contrôle de version et du stockage

En fin de compte, vous pouvez presque toujours les choses version, même avec l'environnement le plus contraint et le plus muré. Le plus souvent, ces systèmes sont toujours livrés avec leur propre versioning (qui est malheureusement souvent assez basique, et propose simplement de revenir aux versions précédentes sans beaucoup de visibilité, en gardant simplement les instantanés précédents). Il n'utilise pas exactement des ensembles de modifications différentielles comme le SCM de votre choix, et il n'est probablement pas adapté pour plusieurs utilisateurs soumettant des modifications simultanément.

Mais quand même, s'ils fournissent une telle fonctionnalité, votre solution est peut-être de suivre nos directives standard bien-aimées ci-dessus, et de les transposer dans ce système de programmation !!

Si le système de stockage est une base de données, il expose probablement des fonctionnalités d'exportation ou peut être sauvegardé au niveau du système de fichiers. S'il utilise un format binaire personnalisé, vous pouvez peut-être simplement essayer de le versionner avec un VCS qui prend bien en charge les données binaires. Vous n'aurez pas de contrôle précis, mais au moins vous aurez votre dos couvert contre les catastrophes et aurez un certain degré de conformité à la reprise après sinistre.

À propos des tests

Implémentez vos tests au sein de la plateforme elle-même et utilisez des outils externes et des tâches d'arrière-plan pour configurer des sauvegardes régulières. Très probablement, vous lancez ces tests de la même manière que vous lancez les programmes développés avec ce système de programmation.

Bien sûr, c'est un travail de piratage et certainement pas à la hauteur de ce qui est commun pour la programmation "normale", mais l'idée est de s'adapter au système tout en essayant de maintenir un semblant de processus de développement logiciel professionnel.

La route est longue et raide ...

Comme toujours avec les environnements de niche et les systèmes de programmation sur mesure, et comme nous l'avons exposé ci-dessus, vous traitez avec des formats étranges, seulement un ensemble limité (ou totalement inexistant) d'outils éventuellement maladroits, et un vide à la place d'une communauté.

La recommandation: Essayez autant que possible d'implémenter les directives ci-dessus en dehors de votre système de programmation sur mesure. Cela garantit que vous pouvez compter sur des outils "communs", qui bénéficient d'un support approprié et d'un dynamisme communautaire.

La solution de contournement: Lorsque ce n'est pas une option, essayez de moderniser ce cadre global dans votre "boîte". L'idée est de superposer ce plan des meilleures pratiques standard de l'industrie au-dessus de votre système de programmation, et d'en tirer le meilleur parti. Le conseil reste valable: définir la structure et les bonnes pratiques, favoriser la conformité.

Malheureusement, cela implique que vous devrez peut-être plonger et faire énormément de travail aux jambes. Donc...

Derniers mots célèbres et demandes humbles:

  • Documentez tout ce que vous faites.
  • Partagez votre expérience.
  • Open Source n'importe quel outil de votre écriture.

En faisant tout cela, vous:

  • non seulement augmenter vos chances d'obtenir le soutien de personnes dans des situations similaires,
  • mais aussi aider d'autres personnes et favoriser la discussion autour de votre pile technologique.

Qui sait, vous pourriez être au tout début d'une nouvelle communauté dynamique de Obscure Language X. S'il n'y en a pas, lancez-en un!

  • Posez des questions sur Stack Overflow ,
  • Peut-être même rédiger une proposition pour un nouveau site StackExchange dans la Zone 51 .

Peut-être que c'est beau à l'intérieur, mais personne n'a un indice jusqu'à présent, alors aidez à abattre ce mur laid et laissez les autres jeter un œil!

464
haylem

La toute première étape serait l'introduction d'un système de contrôle de version (SVN , Git, Mercurial, TFS, etc.). C'est incontournable pour un projet qui aura une refactorisation.

Edit: concernant VSC - Chaque package de contrôle de source peut gérer les binaires, bien qu'avec certaines limitations. La plupart des outils sur le marché ont la possibilité d'utiliser une visionneuse et un éditeur de différence personnalisé, utilisez cette capacité. Les fichiers sources binaires ne sont pas une excuse pour ne pas utiliser le contrôle de version.

Il existe un article similaire sur la façon de gérer le code hérité , il pourrait être une bonne référence à suivre - Conseils sur l'utilisation du code hérité

101
Yusubov

Quand je dois travailler avec du code spaghetti, la première chose sur laquelle je travaille est la modularisation . Trouvez des endroits où vous pouvez tracer des lignes et extraire (plus ou moins) des éléments indépendants de la base de code. Ils ne seront probablement pas très petits, en raison d'un haut degré d'interconnexion et de couplage, mais certaines lignes de modules émergeront si vous les recherchez.

Une fois que vous avez des modules, vous n'êtes plus confronté à la tâche intimidante de nettoyer tout un programme en désordre. Maintenant, à la place, vous avez plusieurs petits modules en désordre indépendants à nettoyer. Maintenant, choisissez un module et répétez à plus petite échelle. Trouvez des endroits où vous pouvez extraire de grandes fonctions dans des fonctions plus petites ou même des classes (si G2 les prend en charge).

C'est beaucoup plus facile si le langage a un système de type suffisamment solide, car vous pouvez demander au compilateur de faire beaucoup de travail pour vous. Vous effectuez un changement quelque part qui rompra (intentionnellement) la compatibilité, puis essayez de compiler. Les erreurs de compilation vous mèneront directement aux endroits qui doivent être modifiés, et lorsque vous cessez de les obtenir, vous avez tout trouvé. Ensuite, exécutez le programme et testez tout! Les tests continus sont d'une importance cruciale lors de la refactorisation.

43
Mason Wheeler

Je ne sais pas si c'est une option pour vous, mais je commencerais à essayer de les convaincre de embaucher plus de développeurs professionnels. De cette façon, ils pourraient se concentrer sur les problèmes de domaine (je suis sûr qu'ils en ont assez).

Je pense que ce sont des gens très intelligents, mais devenir un bon développeur demande beaucoup de temps. Sont-ils prêts à passer autant de temps dans une activité qui n'est pas leur activité principale? À mon humble avis, ce n'est pas la façon d'obtenir les meilleurs résultats.

22
Gilney

Sensationnel. On dirait que vous avez un très gros défi devant vous! Je ferais quelque chose dans le sens suivant:

  • Tout d'abord: Prioriser . Que voulez-vous réaliser en premier? Quel est le plus important pour l'état actuel du projet? Qu'est-ce que vous obtiendrez le plus par rapport au temps qu'il vous faudra pour y arriver.
  • Assurez-vous que vous disposez d'un système de contrôle de version . Git ou Mercurial par exemple.
  • Obtenez une sorte de système d'intégration continue (par exemple Jenkins ) opérationnel.
  • Obtenez un système de suivi des bogues opérationnel. Mantis est assez sympa à mon avis.
  • Regardez dans analyse de code statique (si quelque chose est disponible pour la langue avec laquelle vous travaillez actuellement).
  • Essayez d'obtenir autant de cohérence dans n'importe quoi, de la dénomination des variables aux conventions et directives générales du code dans la base de code.
  • Faites tester le système . À mon avis, cela est extrêmement important pour un gros système comme celui-ci. Utilisez des cas de test pour documenter le comportement existant , peu importe si le comportement vous semble bizarre ou non (généralement, il y a une raison pour laquelle le code a une certaine raison, peut être bon ou mauvais, ou les deux; P). Michael Feathers travaillant efficacement avec Legacy Code est une excellente ressource pour cela.
20
Andreas Johansson

Ils disent que la première étape pour résoudre un problème est d'admettre que vous en avez un. Dans cet esprit, vous pouvez commencer par générer un graphique de dépendance qui illustre le vaste enchevêtrement qui est votre base de code actuelle. Un bon outil pour générer un diagramme de dépendance? a quelques années mais contient quelques pointeurs vers des outils qui peuvent aider à créer de tels graphiques. J'irais avec un très grand graphique laid qui montre autant que possible pour ramener le point à la maison. Parlez des problèmes qui résultent de trop d'interdépendances et peut-être ajoutez ne ligne de Buckaroo Banzai :

Vous pouvez vérifier votre anatomie tout ce que vous voulez, et même s'il peut y avoir des variations normales, en fin de compte, à l'intérieur de la tête, tout a la même apparence. Non, non, non, ne tirez pas dessus. On ne sait jamais à quoi il pourrait être attaché.

À partir de là, présentez un plan pour commencer à redresser le gâchis. Divisez le code en modules aussi autonomes que possible. Soyez ouvert aux suggestions sur la façon de le faire - les gens à qui vous parlez connaissent mieux que vous l'historique et la fonctionnalité du code. Le but, cependant, est de prendre un gros problème et de le transformer en un certain nombre de petits problèmes que vous pouvez ensuite hiérarchiser et commencer à nettoyer.

Quelques points sur lesquels se concentrer:

  • Créez des interfaces propres entre les modules et commencez à les utiliser. L'ancien code peut, par nécessité, continuer à ne pas utiliser ces nouvelles interfaces Nice pendant un certain temps - c'est le problème que vous commencez à résoudre. Mais faites en sorte que tout le monde accepte de n'utiliser que les nouvelles interfaces à l'avenir. S'il y a quelque chose dont ils ont besoin et qui n'est pas dans les interfaces, corrigez les interfaces, ne les contournez pas.

  • Recherchez les cas où la même fonctionnalité a été répétée. Travailler à l'unification.

  • Rappelez à tout le monde de temps en temps que ces changements visent à rendre la vie plus facile, pas plus difficile. La transition peut être douloureuse, mais c'est pour une bonne raison, et plus tout le monde est à bord, plus vite les avantages viendront.

10
Caleb

Après avoir examiné Gensym G2 pendant un certain temps, il semble que la façon d'aborder ce problème dépendra fortement de la quantité de base de code qui ressemble à ceci:

enter image description here

ou ca:

enter image description here

contre cela, gracieuseté de 99 bouteilles de bière :

beer-bottles()

i:integer =99;
j:integer;
constant:integer =-1;

begin
for i=99 down to 1
    do
    j = (i+constant);
        if (i=1) then begin
            post"[i] bottle of beer on the wall";
            post" [i] bottle of beer";
            post" Take one down and pass it around ";
            post" No bottle of beer on the wall"; 
        end 
        else begin
            post"[i] bottles of beer on the wall";
            post" [i] bottles of beer";
            post" Take one down and pass it around ";
            if (i=2) then 
                post" [j] bottle of beer on the wall"
           else
                post" [j] bottles of beer on the wall"; 
           end
    end
end

Dans le cas de ce dernier, vous travaillez avec du code source qui est en fait une quantité connue et certaines des autres réponses offrent des très conseils avisés pour y faire face.

Si la majeure partie de la base de code est la dernière, ou même si un gros morceau l'est, vous allez rencontrer le problème intéressant d'avoir un code qui ne peut probablement pas être refactorisé en raison de son extrême spécialisation, ou pire encore, de quelque chose qui ressemble à il peut être amovible, mais à moins qu'il ne soit correctement documenté, vous ne savez pas si vous supprimez du code critique (pensez à quelque chose du genre opération scram ) qui ne semble pas l'être à au premier coup d'œil.

Bien qu'évidemment, votre première priorité soit d'obtenir une sorte de contrôle de version en ligne, comme indiqué ElYusubov , et il semble que le contrôle de version a été pris en charge depuis la version 8. . Étant donné que G2 est une combinaison de deux méthodologies de langage différentes, il serait probablement plus efficace d'utiliser le contrôle de version fourni avec lui plutôt que d'essayer de trouver autre chose et de le faire fonctionner.

Ensuite, bien que certains préconiseraient probablement de commencer à refactoriser, je suis un ardent défenseur de vous assurer de bien comprendre le système avec lequel vous travaillez avant de commencer à toucher au code, en particulier lorsqu'il s'agit de code et de diagrammes visuels développés par développeurs ayant une formation (ou une formation) formelle en méthodologies de génie logiciel. Le raisonnement est multiple, mais la raison la plus évidente est que vous travaillez avec une application qui a potentiellement plus de 100 années-personnes de travail et que vous devez vraiment vous assurer de savoir ce qu'elle fait et combien il y a de la documentation dedans. Comme vous n'avez pas dit dans quelle industrie le système est déployé, d'après ce que j'ai lu à propos de G2, il semble sûr de supposer qu'il s'agit probablement d'une application essentielle à la mission qui peut même avoir un potentiel pour avoir également des implications pour la sécurité des personnes. . Ainsi, comprendre exactement ce qu'il fait va être très important. S'il y a du code qui n'est pas documenté, travaillez avec les autres membres de l'équipe pour vous assurer que la documentation est mise en place pour que les gens puissent déterminer ce que fait le code.

Ensuite, commencez à emballer les tests unitaires autant que possible de la base de code et des diagrammes visuels. Je dois admettre une certaine ignorance quant à la façon de procéder avec G2, mais cela pourrait presque valoir la peine de créer votre propre cadre de test pour le mettre en place. C'est également le moment idéal pour commencer à présenter les autres membres de l'équipe pour les familiariser avec certaines des pratiques d'ingénierie les plus rigoureuses liées à la qualité du code (c'est-à-dire que tout le code doit avoir des tests unitaires et une documentation).

Une fois que vous avez mis en place des tests unitaires sur une bonne partie du code, vous pouvez commencer à aborder la refactorisation d'une manière telle que celle suggérée par haylem ; Cependant, n'oubliez pas de garder à l'esprit que vous avez affaire à quelque chose qui est destiné à développer des systèmes experts et à le refactoriser pourrait être une bataille difficile. Il s'agit en fait d'un environnement où il y a quelque chose à dire pour pas écrire du code extrêmement générique à certains moments.

Enfin, assurez-vous de prêter une attention particulière à ce que disent les autres membres de l'équipe, simplement parce que la qualité du code et du diagramme n'est pas la meilleure ne les reflète pas nécessairement mal. En fin de compte, pour le moment, ils sont susceptibles d'en savoir plus sur ce que fait l'application que vous, c'est pourquoi il est d'autant plus important pour vous de vous asseoir et de vous assurer de bien comprendre ce qu'elle fait avant d'apporter des modifications radicales.

9
rjzii

Habituellement, les plaintes que vous entendez à l'avance n'ont rien à voir avec les problèmes importants. Après tout, il est tout à fait normal d'entendre ces plaintes dans tous les projets logiciels.

Difficile à comprendre le code? Vérifier. Base de code massive? Vérifier.

Le vrai problème est que les gens partent et quand la nouvelle personne rejoint l'organisation, il y a une désorientation typique. De plus, il y a un problème d'attentes irréalistes et des problèmes de qualité du code.

Voici ce que je voudrais aborder, dans l'ordre:

  1. Sauvegardes, à la fois le serveur et la version locale
  2. Configurer le suivi des bogues
  3. Configurer le système de gestion des versions
  4. Configurer FAQ/Wiki
  5. Premier débriefing de tous les scientifiques/programmeurs
    • Rappelez-leur la règle des 80/20. 20% des bugs sont responsables de 80% des problèmes.
    • Concentrez-vous sur les problèmes les plus importants et désactivez les demandes d'amélioration, etc.
    • Le but ici n'est pas d'effrayer les gens avec une grande liste, mais une liste de petites victoires réalisables. Après tout, vous devez également prouver votre valeur.
  6. Configurer le système de génération
    • Commencez à travailler pour obtenir des versions fiables (cela peut prendre un certain temps)
    • identifier et nommer chaque projet
    • identifier les dépendances cycliques
    • s'il y a des binaires de certains projets open-source, essayez d'obtenir des sources
  7. Identifier comment le code G2 peut être modularisé, par ex. API, services
  8. Identifiez comment le code G2 peut être testé, documenté.
  9. Mettre en place un système de révision de code
  10. Deuxième compte rendu
  11. Identifiez une équipe de crack de meilleurs programmeurs et travaillez avec eux pour envelopper leurs modules.
  12. Les révisions de code sont là à ce stade pour améliorer la communication et la documentation. Gardez les choses faciles à ce stade. Triez tous les problèmes de processus.
  13. Déployez le système auprès d'autres programmeurs. Laissez les membres de l'équipe de crack devenir des pairs mentors pour les autres. N'oubliez pas que la mise à l'échelle est le problème ici. Vous êtes effectivement dans un rôle de gestion.
9
Chui Tey

Des questions comme celles-ci sont la raison pour laquelle le projet Software Carpentry existe.

Au cours des 14 dernières années, nous avons enseigné aux scientifiques et aux ingénieurs des compétences de base en développement de logiciels: contrôle de version, tests, comment modulariser le code, etc. Tous nos documents sont disponibles gratuitement sous une licence Creative Commons, et nous organisons chaque année une douzaine d'ateliers gratuits de deux jours pour aider les gens à démarrer.

Sur cette base, je pense que le meilleur point de départ est probablement l'excellent (court) livre de Robert Glass Facts and Fallacies of Software Engineering: son approche factuelle est une bonne moyen de convaincre les scientifiques que ce que nous leur disons sur les bonnes pratiques de programmation est plus qu'une simple opinion.
Quant aux pratiques spécifiques, les deux que les gens sont les plus disposés à adopter sont le contrôle de version et les tests unitaires; une fois ceux-ci en place, ils peuvent s'attaquer au type de refactorisation systématique décrit par Michael Feathers dans Travailler efficacement avec le code hérité.
Je ne recommande plus The Pragmatic Programmer (beaucoup d'exhortation, difficile pour les novices à mettre en pratique), et je pense que McConnell Code complet est trop pour commencer (bien que ce soit une bonne chose de leur donner six mois ou un an, une fois qu'ils auront maîtrisé les bases).

Je recommande également vivement l'excellent article de Paul Dubois "Maintenir l'exactitude des programmes scientifiques" ( L'informatique en sciences et en génie, mai-juin 2005), qui décrit une approche "défense en profondeur" qui combine une dizaine de pratiques différentes de manière logique et cohérente.

9
Greg Wilson

Je pense que vous devez d'abord clarifier votre situation. Que veulent-ils de vous?

  • Il est très peu probable qu'ils veuillent que vous appreniez une langue ancienne, car cela semble maintenant une impasse: il y a une chance décroissante de trouver quelqu'un qui sait ou qui veut apprendre G2, donc les connaissances seront enfouies dans le tas de code qui s'effondre lorsque les scientifiques actuels partent ou le code tout patché échoue de plus en plus souvent.
  • Les scientifiques (ou certains d'entre eux) sont-ils prêts à apprendre un nouveau langage et de nombreux paradigmes de programmation? Ou veulent-ils séparer la programmation et l'activité scientifique à long terme, et peut-être avoir plus de programmeurs si nécessaire? Cela semble une séparation rationnelle et plus efficace de l'expertise.

Je pense que l'exigence fondamentale ici est de "sauvegarder les connaissances dans le système", donc vous devez aller les fouiller!

La première tâche consiste à rédiger une documentation.

Analysez la structure et les exigences comme s'il s'agissait d'une nouvelle tâche, mais à l'aide d'un système existant. Ils seront ravis parce que vous DEMANDER au lieu d'ENSEIGNER d'abord - et vous obtiendrez rapidement suffisamment de connaissances de base, mais plus organisées du point de vue d'un programmeur: "que se passe-t-il ici?" Les documents (structure statique du système, flux de travail, composants, problèmes) seront immédiatement précieux pour eux et leur montreront peut-être des informations plus pertinentes que pour vous (certains gars peuvent avoir "AHA!" Et commencer à corriger certains codes immédiatement ) ...

Vous devriez alors commencer à demander où ils veulent aller?

S'ils sont prêts à s'éloigner de G2 , quel système veulent-ils voir (plate-forme, langage, interface, structure générale)? Vous pouvez commencer à écrire un wrapper externe autour du système si possible, ayant la structure cible, mais en conservant les composants d'origine, démarrant ainsi lentement une sorte de framework qui permet à de nouveaux composants d'être implémentés dans cet environnement cible. Vous devez trouver les services de base (connexions de données persistantes et "toolkits": calcul de base, dessin, ... bibliothèques), et ainsi vous leur fournissez un environnement familier dans une nouvelle plateforme et un nouveau langage, qui permet la transition soit par vous ou les: reprendre les anciens codes un par un, les réimplémenter (et les NETTOYER!) dans le nouvel environnement. Quand c'est prêt, ils connaissent la nouvelle langue; et la couche de service (principalement faite par vous, désolé) est prête à héberger les nouveaux composants.

S'ils ne bougent pas , vous devez apprendre G2 et y créer le cadre modulaire dans lequel vous ou ils doivent déplacer les composants (avec nettoyage) . Quoi qu'il en soit, le langage n'est qu'une sérialisation de données et d'arborescence d'algorithmes ...

Lors de l'analyse et de la rédaction des documents, lire, utiliser et publier des modèles de conception GoF! :-)

... mes 2 cents

7
Lorand Kedves

Je viens de terminer une série de présentations sur les principes de Robert Martin SOLID pour mes collègues. Je ne sais pas dans quelle mesure ces principes se traduisent en G2, mais puisque vous en recherchez 5 -7 principes fondamentaux, ceux-ci semblent être un ensemble bien établi pour commencer. Si vous voulez arrondir à 7, vous pouvez commencer avec DRY et lancer Fail-Fast.

4
StriplingWarrior

"Le programme lui-même est un modèle physique d'une usine de traitement chimique complexe ..."

"Puisque G2 est comme du non-code, mais plutôt du code automatisé écrit par une interface graphique gadget ..." - Erik Reppen

En supposant que l'objectif principal de votre logiciel est de simuler (peut-être optimiser, exécuter des estimations de paramètres sur) une usine chimique complexe , ou des parties d'une usine ... alors je ' je voudrais lancer une suggestion assez différente:

Vous pourriez bien envisager d'utiliser un langage de modélisation mathématique de haut niveau pour extraire l'essence, les modèles mathématiques de base, hors logiciel codé à la main.

Ce que fait un langage de modélisation, c'est de dissocier la description du problème des algorithmes utilisés pour résoudre le problème. Ces algorithmes sont généralement applicables à la plupart des simulations/optimisations d'une classe donnée (par exemple, les processus chimiques), auquel cas ils ne devraient vraiment pas être réinventés et maintenus en interne.

Trois packages commerciaux largement utilisés dans votre industrie sont: gPROMS, Aspen Custom Modeller, et (si vos modèles n'incluent pas de phénomènes répartis sur des domaines spatiaux), il existe des packages logiciels basés sur Modelica, tels que Dymola.

Tous ces packages prennent en charge les "extensions" d'une manière ou d'une autre, de sorte que si vous avez des parties de vos modèles qui nécessitent une programmation personnalisée, elles peuvent être encapsulées dans un objet (par exemple, un .DLL) qui peut être référencé par les équations dans le modèle. Pendant ce temps, l'essentiel de votre modèle reste succinct, décrit sous une forme facilement lisible par les scientifiques directement. C'est une bien meilleure façon de capturer les connaissances et la propriété intellectuelle de votre entreprise.

La plupart de ces programmes devraient également vous permettre de "démarrer petit" et de porter de petites parties (sous-modèles) de votre code monolithique dans leur format, en étant appelés en externe. Cela peut être un bon moyen de maintenir un système de travail et de le valider une pièce à la fois.

Clause de non-responsabilité complète: J'ai travaillé en tant qu'ingénieur logiciel dans l'entreprise derrière gPROMS pendant 8 ans. Pendant ce temps, j'ai vu (et parfois incorporé) des exemples de logiciels personnalisés (par exemple, provenant du monde universitaire) qui avaient commencé petit et bien rangé, mettant en œuvre une solution ou un algorithme intelligent, mais qui ont ensuite explosé au fil des ans avec des extensions et des modifications - sans les conseils utiles de un ingénieur logiciel pour le garder propre. (Je suis un grand fan des équipes multidisciplinaires.)

Je peux donc dire avec une certaine expérience que certains choix clés mal faits au début du développement d'un logiciel (comme un langage ou une bibliothèque de clés) ont tendance à rester et à causer de la douleur pendant très longtemps ... Ils ont déjà `` façonné '' le logiciel autour d'eux. Il me semble que vous pourriez être confronté à de nombreuses années de pur nettoyage de code ici. (J'hésite à utiliser des chiffres, mais je pense à plus de 10 années-personnes, peut-être beaucoup plus si vous ne pouvez pas transférer le code de G2 vers quelque chose qui prend en charge de bons outils de refactorisation automatisés comme Eclipse/Java quick-smart.)

Bien que mon statut par défaut soit "refactoriser et maintenir un système fonctionnel", je pense également qu'une fois qu'un problème devient "trop ​​important", un changement/réécriture plus radical devient globalement plus rapide. (Et apporte peut-être des avantages supplémentaires, comme passer à une technologie plus moderne.) Je dis qu'avec une certaine expérience du portage vers une nouvelle plate-forme logicielle, mais d'après ce que je comprends, c'est encore plus dramatique avec un portage vers un package de modélisation mathématique.

Pour donner une certaine perspective, vous pourriez être assez étonné de la réduction de taille. Par exemple. les 200 000 LoC pourraient en fait être représentés dans quelque chose comme 5 000 lignes d'équations (OK, je suppose ici, mais je pourrais essayer de vous obtenir un témoignage réel d'amis dans l'entreprise); plus quelques modules de fonction relativement petits écrits en quelque chose comme C (par exemple, des calculs de propriétés physiques - bien que des packages standard puissent exister en fonction de votre processus chimique). C'est parce que vous jetez littéralement le code de la solution algorithmique et laissez une "pile" polyvalente de solveurs mathématiques faire le travail. Une fois que vous avez exécuté des simulations, vous pouvez faire beaucoup plus avec elles, comme optimiser le processus - sans changer une ligne de code.

Enfin, je dirais: si la seule documentation fiable des différents modèles mathématiques (et algorithmes) est le code lui-même, vous voudrez l'aide des scientifiques et des auteurs originaux pour aider à extraire ces modèles, dès que possible, pas des années plus tard lorsque certains d'entre eux ont peut-être évolué. Ils devraient trouver qu'un langage de modélisation mathématique est un moyen très naturel de capturer ces modèles - ils peuvent même (horreur de choc) aimer (ré) écrire.


Enfin, comme ma réponse est peut-être hors de propos, je voudrais juste ajouter un livre de plus à la liste des bons livres déjà référencés ici: Clean Code de Robert Martin. Plein de conseils simples (et justifiés) faciles à apprendre et à appliquer, mais qui pourraient faire toute la différence pour les personnes qui développent un nouveau code dans votre entreprise.

3
Luke Usherwood

Le seul problème de production ressemble à un problème de gestion du changement. Si tel est le cas et que le logiciel le fait autrement, le premier conseil que je donnerais est de résister à l'envie d'en faire trop et trop vite.

Le contrôle des sources, la refactorisation, des développeurs plus entraînés sont tous de bonnes suggestions, mais si c'est la première fois que vous avez dû faire face à ce type de problème en se déplaçant lentement et en effectuant des changements contrôlés ne peut pas être suffisamment souligné.

L'envie de déchiqueter le désordre sera parfois grande, mais jusqu'à ce que vous en ayez suffisamment ingénierie inverse que vous savez que vous pouvez tester votre version de remplacement de manière adéquate, vous devez être très prudent.

3
Bill

Les principes les plus importants pour travailler dans une telle situation sont:

  1. Sois patient. Un trou qui a mis 20 ans à creuser ne sera pas comblé dans quelques semaines.

  2. Sois positif. Résistez à la tentation de vous plaindre et de vous plaindre.

  3. Soyez pragmatique. Regardez un changement positif que vous pouvez accomplir en une journée et faites-le aujourd'hui. Vous avez encore un système de contrôle de version? Mettez-le en œuvre et formez des gens. Ensuite, regardez et voyez si vous pouvez automatiser les tests (tests unitaires ou quelque chose de similaire). Rincer. Répéter.

  4. Soyez un modèle. Montrez (ne dites pas simplement) aux gens comment fonctionne l'agilité en étant agile. Les trois premiers points ci-dessus sont les clés pour être un bon gars, qui est le prédécesseur d'un gars agile efficace. À mon avis, les gens qui sont d'admirables développeurs ne sont pas seulement intelligents, ils sont également bons, modélisent les employés et les collègues.

  5. Cartographiez votre territoire. J'ai une technique pour cartographier les bases de code héritées géantes. Je clone le dépôt, fais une copie de travail, puis j'essaie de changer quelque chose et de voir ce qui se casse. En enquêtant sur le couplage (via l'état global, ou des API cassées, ou un manque d'API cohérente ou d'abstractions ou d'interfaces pour programmer contre) et en lisant le code qui casse lorsque je change les choses, je découvre la cruauté, je pose des questions qui conduisent à des idées du reste de l'équipe (Oh, nous avons ajouté que parce que Boss X il y a 5 ans l'exigeait, cela n'a jamais fonctionné!). Au fil du temps, vous obtiendrez une carte mentale du territoire. Une fois que vous savez quelle est sa taille, vous en saurez suffisamment pour faire votre carte et rentrer à la maison. Encouragez les autres à cartographier le territoire de votre base de code géante et à développer les connaissances techniques de l'équipe. Certaines personnes rechignent à la "documentation" parce qu'elle n'est pas agile. Peu importe. Je travaille aussi dans des environnements scientifiques, et la documentation est roi pour moi, les manifestes agiles soient damnés.

  6. Créez de petites applications. Lorsque je travaille avec une base de code héritée, je trouve que je suis réduit en pâte. Je retrouve mon esprit en créant de petites applications d'aide. Peut-être que ces applications vous aideront à lire, à comprendre et à modifier cette base de code G2 géante. Vous pouvez peut-être créer un mini IDE ou outil d'analyse qui vous aidera à travailler dans votre environnement. Il existe de nombreux cas où la méta-programmation et la création d'outils ne vous aideront pas seulement à sortir du géant impasses que les bases de code héritées vous imposent, elles donnent également à votre cerveau la capacité de voler sans restriction de votre langage G2. Écrivez vos outils et assistants dans la langue dans laquelle vous pouvez les faire le plus rapidement et le mieux. Pour moi, ces langues incluent Python et Delphi . Si vous êtes un gars de Perl, ou que vous AIMEZ réellement la programmation en C++ ou C #, alors écrivez vos outils d'aide dans ce langage. Apprenez au reste de l'équipe à créer de petites applications et outils d'aide, et des "composants" et vous " Nous verrons finalement que votre base de code héritée n'est pas si intimidante après tout.

3
Warren P
  1. Contrôle de révision: montrez aux experts du domaine l'avantage de pouvoir revenir en arrière, voir qui a changé quoi, etc. (C'est plus difficile avec les fichiers tout binaires, mais si le contenu est en effet du code, il y a sûrement un une sorte de convertisseur G2 en texte qui peut activer les différences.)

  2. Intégration et test continus: impliquez les experts du domaine dans la création de tests de bout en bout (plus faciles, car ils doivent déjà avoir des entrées et des sorties attendues quelque part) et de petits tests unitaires (plus difficiles, car le code spaghetti est probablement implique de nombreuses variables globales) qui couvrent presque toutes les fonctionnalités et les cas d'utilisation.

  3. Refactor common code en routines et composants réutilisables. Les personnes non logicielles sans contrôle de révision copient et collent probablement des centaines de lignes à la fois pour créer des routines. Trouvez-les et refactorisez-les, montrant que tous les tests réussissent et que le code est devenu plus court. Cela vous aidera également à apprendre son architecture. Si vous êtes chanceux au moment où vous devez commencer à prendre les décisions architecturales difficiles, vous pourriez être à 100KLOC.

Politiquement, si vous trouvez de la résistance de la part des anciens dans ce processus, engagez un consultant pour venir parler de la bonne méthodologie logicielle. Assurez-vous d'en trouver une bonne dont vous êtes d'accord avec les opinions et demandez à la direction d'acheter la nécessité du consultant même si les experts du domaine ne le font pas. (Ils devraient être d'accord - après tout, ils vous ont embauché, alors ils réalisent évidemment qu'ils ont besoin d'une expertise en génie logiciel.) C'est une astuce qui gaspille de l'argent, bien sûr, mais la raison en est que si vous - le nouveau programmeur de jeunes hotshot - dites ils ont besoin de faire quelque chose, ils peuvent l'ignorer. Mais si la direction paie 5000 $ à un consultant pour venir lui dire ce qu'il doit faire, elle y fera plus confiance. Points bonus : demandez au consultant de conseiller deux fois plus de changements que vous le souhaitez, alors vous pouvez être le "bon gars" et vous ranger du côté des experts du domaine , compromettant de ne changer que la moitié autant que le consultant l'a suggéré.

3
Conrad Poelman

Faites d'abord l'analyse.

Je ferais une analyse avant de décider quoi enseigner. Découvrez où se trouvent les plus gros points douloureux. Utilisez-les pour hiérarchiser les pratiques à suivre.

Introduisez seulement quelques changements à la fois (dans une situation similaire j'ai fait 2-3 entraînements toutes les 2 semaines) .

Je limiterais les pratiques à ~ 3 en fonction du niveau de changement du style de programmation de SDLC; jusqu'à ce qu'ils commencent à se familiariser avec eux (je pousserais à introduire 1 nouveau changement toutes les ~ 1-2 semaines car ils se familiarisent avec l'idée d'apprendre de nouvelles approches). C'est également une bonne idée d'identifier les critères de réussite. Ce que la pratique devrait accomplir (même si c'est un objectif doux comme le moral de l'équipe). De cette façon, vous pouvez montrer si c'est efficace ou non.

  • Pourquoi limiter le nombre de changements?

Même si vous supposez que ces personnes veulent être de meilleurs programmeurs et sont ouvertes à l'apprentissage, il y a des limites à combien et à quelle vitesse les gens peuvent apprendre de nouveaux concepts et les appliquer; surtout s'ils n'ont pas de fondation CS ou ont déjà participé à un cycle de vie de développement logiciel.

Ajoutez une réunion de récapitulation hebdomadaire pour discuter de la façon dont les pratiques les ont affectées.

La réunion devrait être utilisée pour discuter de ce qui s'est bien passé et de ce qui doit fonctionner. Permettez-leur d'avoir une voix et d'être collaboratifs. Discutez et planifiez pour résoudre les problèmes qu'ils rencontrent et pour prévisualiser les prochains changements à venir. Gardez la réunion concentrée sur les pratiques et leur application. Faites un peu d'évangélisation sur les avantages qu'ils devraient commencer à voir en appliquant les pratiques.

Certaines pratiques ont priorité.

La bonne utilisation d'un système de contrôle de version (OMI) l'emporte sur tout le reste. Juste derrière se trouvent des leçons de modularisation, de couplage/cohésion et de suivi des tickets de fonctionnalité/bug.

Supprimez les pratiques qui ne fonctionnent pas.

N'ayez pas peur de vous débarrasser des pratiques qui ne fonctionnent pas. S'il y a un coût élevé et peu ou pas d'avantages, supprimez la pratique.

L'amélioration est un processus.

Transmettre qu'une amélioration soutenue et cohérente est un processus. Identifiez les plus gros points douloureux, appliquez une solution, attendez/entraînez, puis répétez. Il se sentira très lentement au début jusqu'à ce que vous développiez un élan. Gardez tout le monde concentré sur les améliorations à venir et celles qui sont déjà réussies.

2
dietbuddha

Je jetterais ce qui suit:

  1. Il y a un programmeur ici. Visser la politique. Ils connaissent leur métier. Vous connaissez le vôtre. Marquez ce territoire même si vous devez pisser dessus. Ce sont des scientifiques. Ils peuvent respecter ce genre de chose ou devraient le faire, car ils font à peu près constamment la même chose. Par tous les moyens possibles, marquez les limites maintenant. C'est ce que je vais corriger. C'est ce dont je ne peux pas être responsable.

  2. Les scientifiques écrivent/testent les algorithmes. Les scientifiques qui le souhaitent peuvent écrire leurs propres algorithmes dans 1 à 3 langues sur lesquelles tout le monde peut s'entendre pour que vous les convertissiez en code de base. Cela met à l'épreuve leurs trucs sur eux. Au-delà de cela, ils vont devoir vous aider à isoler les trucs scientifiques importants par rapport au bon Dieu sait ce qu'ils ont fait pour l'architecture. La base de code est arrosée. Il y aura beaucoup de coupures et de brûlures qui devront être faites. Donnez-leur des options pour vous remettre des versions de travail de trucs qui emploient ce qu'ils savent le mieux afin que vous puissiez faire ce que vous faites le mieux. Collez leurs connaissances dans une boîte dont ils sont responsables mais avec laquelle vous pouvez travailler. Idéalement, lorsque les choses se passent bien dans un méga-refactor, les conversations porteront davantage sur les types de choses passionnantes que vous pouvez faire avec l'interface plutôt que sur ce que tentacule Z9 de drBobsFuncStructObjThingMk2_0109 a fait quand il a énervé la var globale X19a91.

  3. Utilisez un langage adapté aux événements avec des fonctions de première classe si vous le pouvez. Lorsque tout le reste échoue, déclencher un événement ou lancer un rappel à un objet avec une interface et un mécanisme d'état qui a du sens peut être un énorme gain de temps lorsque vous êtes à genoux dans un code qui n'a aucun sens sanglant et très probablement jamais volonté. Les scientifiques semblent aimer Python. Pas difficile de coller des trucs en C intensifs en mathématiques de bas niveau avec ça. Je dis juste

  4. Recherchez quelqu'un qui a résolu ce problème ou un problème similaire. Passez du temps à faire des recherches sérieuses. Ces gars ont entendu parler de G2 par quelqu'un.

  5. Modèles de conception. Adaptateurs. Utilisez-les. Utilisez-les beaucoup dans des situations comme celle-ci.

  6. Apprenez ce que vous pouvez de la science. Plus vous en savez, mieux vous pouvez déterminer l'intention dans le code.

2
Erik Reppen

Le contrôle du code source est l'étape n ° 1, comme cela a déjà été indiqué à plusieurs reprises. Bien que les personnes avec lesquelles vous travaillez ne soient pas des développeurs professionnels et ne répondent pas à beaucoup de jumbo d'entreprise ou agile. Ce ne sont pas non plus des singes de code de bas niveau et essayer de les traiter comme ça en les forçant à faire les choses `` à votre façon '' ne volera pas.

Vous devez examiner ce qui existe. S'ils n'ont pas utilisé le contrôle du code source, alors il suffit d'identifier les bonnes versions du code (si possible) et de déterminer tous les livrables possibles. Ensuite, vous aurez la tâche d'enseigner à vos collègues comment utiliser le contrôle du code source et de les convaincre que cela en vaut la peine. Commencez par les avantages!

Pendant que vous faites cela, trouvez d'autres fruits bas et corrigez ces problèmes.

Par-dessus tout, écoutez ce qu'ils ont à dire et travaillez à améliorer leur situation. Ne vous inquiétez pas d'essayer d'apposer votre marque sur ce qu'ils font.

Bonne chance!

0
Bill

Il semble que la première étape consiste à vendre à l'équipe la nécessité d'investir dans une nouvelle méthodologie logicielle. Selon votre déclaration, il n'y a pas de consensus au sein de l'équipe, et vous en aurez besoin pour pouvoir avancer avec une lente "mise à niveau" du code.

Je prendrais (si possible) personnellement les dures leçons apprises et présenterais chacun des concepts clés que vous souhaitez comme solution au problème dans l'industrie du logiciel.

Par exemple. deux développeurs ont eu des copies différentes et ont fini par déployer une version hybride non testée -> Introduire le contrôle de version, la branche et les tests.

Quelqu'un a supprimé quelques lignes de code qu'il ne comprenait pas et a provoqué une panne -> introduire DDD.

Si les leçons difficiles ne sont pas partagées avec vous de manière suffisamment détaillée, montrez simplement vos propres exemples de la façon dont les choses ont mal tourné lorsque cette discipline n'a pas été respectée.

0
M Afifi