Note du modérateur Dix- sept réponses
ont déjà été posées sur cette question. Avant de poster une nouvelle réponse, veuillez lire les réponses existantes et assurez-vous que votre point de vue n'est pas déjà suffisamment couvert.
J'ai suivi certaines des pratiques recommandées dans le livre "Code propre" de Robert Martin, en particulier celles qui s'appliquent au type de logiciel avec lequel je travaille et celles qui me semblent logiques (je ne le suis pas comme un dogme) .
Un effet secondaire que j’ai remarqué, cependant, est que le code «propre» que j’écris est plus codé que si je ne suivais pas certaines pratiques. Les pratiques spécifiques qui mènent à ceci sont:
- Conditionnel d'encapsulation
Donc au lieu de
if(contact.email != null && contact.emails.contains('@')
Je pourrais écrire une petite méthode comme celle-ci
private Boolean isEmailValid(String email){...}
- Remplacement d'un commentaire en ligne par une autre méthode privée, afin que le nom de la méthode se décrive lui-même plutôt que d'avoir un commentaire en ligne par dessus
- Une classe ne devrait avoir qu'une seule raison de changer
Et quelques autres. Le fait est que ce qui pourrait être une méthode de 30 lignes finit par être une classe, à cause des méthodes minuscules qui remplacent les commentaires et encapsulent les conditionnelles, etc. Lorsque vous réalisez que vous avez autant de méthodes, alors il mettez toutes les fonctionnalités dans une seule classe, alors que cela aurait dû être une méthode.
Je suis conscient que toute pratique poussée à l'extrême peut être nocive.
La question concrète à laquelle je cherche une réponse est:
Est-ce un sous-produit acceptable d'écrire un code propre? Si tel est le cas, quels arguments puis-je utiliser pour justifier le fait que davantage de lettres de crédit ont été écrites?
L'organisation ne se préoccupe pas spécifiquement de plus de LOC, mais plus de LOC peut donner lieu à de très grandes classes (qui pourraient être remplacées par une méthode longue sans un tas de fonctions utilitaires utilisables une seule fois pour des raisons de lisibilité).
Lorsque vous voyez une classe assez grande, cela donne l’impression que la classe est suffisamment occupée et que sa responsabilité est terminée. Vous pourriez donc finir par créer plus de classes pour réaliser d'autres fonctionnalités. Le résultat est alors beaucoup de classes, toutes faisant "une chose" à l'aide de nombreuses méthodes de petits assistants.
CECI est la préoccupation spécifique ... ces classes pourraient être une classe unique qui réalise toujours "une chose", sans l'aide de nombreuses petites méthodes. Ce pourrait être une classe unique avec peut-être 3 ou 4 méthodes et quelques commentaires.
la source
Réponses:
Ces personnes ont correctement identifié quelque chose: elles veulent que le code soit plus facile à gérer. Là où ils se sont trompés, c'est en supposant que moins il y a de code, plus il est facile à maintenir.
Pour que le code soit facile à gérer, il doit être facile à modifier. De loin, le moyen le plus simple d’obtenir un code facile à modifier est d’avoir un ensemble complet de tests automatisés qui échoueront si votre modification est révolutionnaire. Les tests sont du code, alors écrire ces tests va grossir votre base de code. Et c'est une bonne chose.
Deuxièmement, pour déterminer ce qui doit changer, votre code doit être à la fois facile à lire et à raisonner. Un code très concis, dont la taille est réduite pour garder le compte à rebours est très improbable. De toute évidence, il faut trouver un compromis car un code plus long prendra plus de temps à lire. Mais si c'est plus rapide à comprendre, alors ça vaut le coup. S'il n'offre pas cet avantage, cette verbosité cesse d'être un avantage. Mais si un code plus long améliore la lisibilité, c'est encore une bonne chose.
la source
Oui, c'est un sous-produit acceptable, et la justification est qu'il est maintenant structuré de sorte que vous n'avez pas à lire la plupart du code la plupart du temps. Au lieu de lire une fonction de 30 lignes chaque fois que vous effectuez un changement, vous lisez une fonction de 5 lignes pour obtenir le flux global, et peut-être quelques fonctions auxiliaires si votre modification touche cette zone. Si votre nouvelle classe "extra" est appelée
EmailValidator
et que vous savez que votre problème n’est pas lié à la validation du courrier électronique, vous pouvez ignorer la lecture.Il est également plus facile de réutiliser des éléments plus petits, ce qui a tendance à réduire le nombre de lignes pour l'ensemble de votre programme. Un
EmailValidator
peut être utilisé partout. Certaines lignes de code validant le courrier électronique mais regroupées avec le code d'accès à la base de données ne peuvent pas être réutilisées.Et ensuite, réfléchissez à ce qui doit être fait si les règles de validation des courriers électroniques doivent être modifiées - vous préférez: un emplacement connu; ou de nombreux endroits, peut-être en manque quelques-uns?
la source
iterations < _maxIterations
dans une méthode appeléeShouldContinueToIterate
est stupide .Bill Gates était réputé pour avoir déclaré: "Mesurer les progrès de la programmation à l'aide de lignes de code revient à mesurer les progrès de la construction de l'avion en termes de poids."
Je suis humblement d'accord avec ce sentiment. Cela ne veut pas dire qu'un programme doit s'efforcer d'avoir plus ou moins de lignes de code, mais que ce n'est pas ce qui compte en définitive pour créer un programme fonctionnel et fonctionnel. Il est utile de se rappeler que la raison ultime de l'ajout de lignes de code supplémentaires est qu'il est théoriquement plus lisible de cette façon.
On peut avoir des désaccords quant à savoir si un changement donné est plus ou moins lisible, mais je ne pense pas que vous auriez tort de modifier votre programme, car vous pensez que vous le rendez ainsi plus lisible. Par exemple, faire un
isEmailValid
pourrait être considéré comme superflu et inutile, surtout s'il est appelé une seule fois par la classe qui le définit. Cependant, je préférerais de beaucoup voir uneisEmailValid
condition plutôt qu'une chaîne de conditions AND, dans laquelle je dois déterminer ce que chaque condition vérifie et pourquoi elle est vérifiée.Vous rencontrez des problèmes lorsque vous créez une
isEmailValid
méthode qui a des effets secondaires ou qui vérifie des éléments autres que le courrier électronique, car cela est pire que de simplement tout écrire. C'est pire parce que c'est trompeur et que je risque de rater un bogue à cause de cela.Bien que, de toute évidence, vous ne le fassiez pas dans ce cas, je vous encourage donc à continuer comme vous le faites. Vous devriez toujours vous demander si, en apportant le changement, il est plus facile à lire et si tel est votre cas, faites-le!
la source
Il s’agit de perdre de vue le but réel.
Ce qui compte, c’est de réduire les heures consacrées au développement . Cela se mesure en temps (ou en un effort équivalent) et non en lignes de code.
Cela revient à dire que les constructeurs automobiles devraient construire leurs voitures avec moins de vis, car cela prend un temps non nul pour mettre chaque vis. Bien que cela soit correct du point de vue pédagogique, la valeur marchande d'une voiture n'est pas définie par son nombre de vis. ou n'a pas. Avant tout, une voiture doit être performante, sûre et facile à entretenir.
Le reste de la réponse montre comment un code propre peut générer des gains de temps.
Enregistrement
Prenez une application (A) qui n’a pas d’enregistrement. Maintenant, créez l'application B, qui est la même application A mais avec la journalisation. B aura toujours plus de lignes de code et vous devrez donc écrire plus de code.
Mais beaucoup de temps passera à enquêter sur les problèmes et les bugs et à déterminer ce qui ne va pas.
Pour l'application A, les développeurs seront bloqués en train de lire le code et devront reproduire en permanence le problème et parcourir le code pour trouver la source du problème. Cela signifie que le développeur doit tester du début à la fin, dans chaque couche utilisée, et doit observer chaque élément logique utilisé.
Peut-être a-t-il de la chance de le trouver immédiatement, mais peut-être que la réponse sera au dernier endroit qu'il pense regarder.
Pour l'application B, en supposant une journalisation parfaite, un développeur observe les journaux, peut identifier immédiatement le composant défectueux et sait désormais où chercher.
Cela peut être une question de minutes, heures ou jours économisés; en fonction de la taille et de la complexité de la base de code.
Régressions
Prenez l’application A, qui n’est pas du tout compatible avec le séchage.
Prenez l’application B, qui est DRY, mais qui a nécessité plus de lignes à cause des abstractions supplémentaires.
Une demande de modification est déposée, ce qui nécessite une modification de la logique.
Pour l'application B, le développeur modifie la logique (unique, partagée) en fonction de la demande de modification.
Pour l'application A, le développeur doit modifier toutes les instances de cette logique dans lesquelles il se souvient de son utilisation.
Cela peut entraîner un énorme gaspillage de temps. Pas seulement en développement, mais à la chasse et à la découverte du bogue. L'application peut commencer à se comporter de manière erratique d'une manière que les développeurs ne peuvent pas comprendre facilement. Et cela conduira à de longues sessions de débogage.
Interchangeabilité avec les développeurs
Développeur A créé l’application A. Le code n’est ni propre, ni lisible, mais il fonctionne comme un charme et a été exécuté en production. Sans surprise, il n'y a pas de documentation non plus.
Le développeur A est absent pendant un mois en raison de vacances. Une demande de changement d'urgence est déposée. Il ne faut pas attendre encore trois semaines pour que Dev A revienne.
Le développeur B doit exécuter ce changement. Il doit maintenant lire l'intégralité de la base de code, comprendre comment tout fonctionne, pourquoi cela fonctionne et ce qu'il essaie d'accomplir. Cela prend des années, mais supposons qu'il puisse le faire en trois semaines.
Simultanément, l’application B (créée par dev B) a une urgence. Dev B est occupé, mais Dev C est disponible, même s'il ne connaît pas la base de code. Qu'est-ce qu'on fait?
Dev A revient de ses vacances et constate que B n'a pas compris le code et l'a donc mal appliqué. Ce n'est pas la faute de B, puisqu'il a utilisé toutes les ressources disponibles, le code source n'était tout simplement pas lisible. Est-ce que A doit maintenant passer du temps à fixer la lisibilité du code?
Tous ces problèmes, et bien d’autres encore, finissent par perdre du temps . Oui, à court terme, le code propre nécessite plus d' efforts maintenant , mais il finira par payer des dividendes à l'avenir lorsque des bugs inévitables / changements doivent être pris en compte.
La direction doit comprendre qu'une tâche courte maintenant vous évitera plusieurs tâches longues dans le futur. Ne pas planifier est la planification à l'échec.
Mon explication au goto demande à la direction ce qu’elle préférerait: une application avec une base de code 100KLOC pouvant être développée en trois mois, ou une base de code 50KLOC pouvant être développée en six mois.
Ils choisiront évidemment le temps de développement le plus court, car la direction ne se soucie pas de KLOC . Les gestionnaires qui se concentrent sur KLOC font de la micro-gestion tout en ignorant ce qu’ils essaient de gérer.
la source
Je pense que vous devriez faire très attention à l’application de pratiques de «code propre» au cas où elles conduiraient à une plus grande complexité générale. La refactorisation prématurée est la racine de nombreuses mauvaises choses.
Extraire un conditionnel à une fonction conduit à un code plus simple à l'endroit où le conditionnel a été extrait , mais conduit à une complexité globale car vous disposez maintenant d'une fonction visible à partir de plusieurs points du programme. Vous ajoutez un léger fardeau de complexité à toutes les autres fonctions où cette nouvelle fonction est maintenant visible.
Je ne dis pas que vous ne devriez pas extraire le conditionnel, mais simplement que vous devriez considérer attentivement si vous en avez besoin.
Dans tout ce qui précède, il existe une raison pour l'extraction, au-delà du "code propre". En outre, vous ne douteriez probablement même pas que c'était la bonne chose à faire.
En cas de doute, je choisirais toujours le code le plus simple et le plus direct.
la source
Je ferais remarquer qu'il n'y a rien de fondamentalement faux avec ceci:
Au moins en supposant que c'est utilisé cette fois.
Je pourrais avoir des problèmes avec cela très facilement:
Quelques points à surveiller:
S'il est utilisé une fois, est simple à analyser et prend moins d'une ligne, je suppose que la décision sera prise. Ce n'est probablement pas quelque chose que j'appellerais s'il ne s'agissait pas d'un problème particulier d'une équipe.
D'autre part, j'ai vu des méthodes faire quelque chose comme ça:
Cet exemple n'est évidemment pas DRY.
Ou même juste cette dernière déclaration peut donner un autre exemple:
L’objectif devrait être de rendre le code plus lisible:
Un autre scénario:
Vous pourriez avoir une méthode comme:
Si cela correspond à votre logique métier et n’est pas réutilisé, il n’ya pas de problème ici.
Mais quand quelqu'un demande "Pourquoi" @ "est-il enregistré, car ce n'est pas correct!" et vous décidez d’ajouter une validation réelle, puis extrayez-la!
Vous serez heureux de l'avoir fait lorsque vous avez également besoin de créer un compte pour le deuxième compte de messagerie du président Pr3 $ sid3nt @ h0m3! @ Mydomain.com et que vous décidez de tout mettre en œuvre pour essayer de soutenir RFC 2822.
Sur la lisibilité:
Si votre code est aussi clair, vous n'avez pas besoin de commentaires ici. En fait, vous n'avez pas besoin de commentaires pour dire ce que le code fait le plus souvent, mais plutôt pourquoi il le fait:
Que les commentaires ci-dessus une déclaration if ou à l'intérieur d'une méthode minuscule est pour moi pédant. Je pourrais même faire valoir le contraire d'utile avec de bons commentaires dans une autre méthode, car il faudrait maintenant naviguer vers une autre méthode pour voir comment et pourquoi il fait ce qu'il fait.
En résumé: ne mesurez pas ces choses; Concentrez-vous sur les principes sur lesquels le texte a été construit (DRY, SOLID, KISS).
la source
Whether the comments above an if statement or inside a tiny method is to me, pedantic.
C'est un problème de "paille qui a cassé le dos du chameau". Vous avez raison de dire que cette chose-là n'est pas particulièrement difficile à lire. Mais si vous avez une grande méthode (par exemple une grande importation) qui a des dizaines de ces petites évaluations, ayant ces encapsulé dans les noms de méthode lisibles (IsUserActive
,GetAverageIncome
,MustBeDeleted
, ...) deviendra une amélioration notable à la lecture du code. Le problème avec l'exemple, c'est qu'il n'observe qu'une paille, pas le paquet en entier qui casse le dos du chameau.if (contact.email != null && contact.email.contains('@'))
est bogué. Si if est faux, aucune des autres lignes si ne peut être vraie. Ce n'est pas du tout visible dans leLooksSortaLikeAnEmail
bloc. Une fonction contenant une seule ligne de code n’est guère meilleure qu’un commentaire expliquant le fonctionnement de la ligne.Clean Code est un excellent livre, qui mérite d'être lu, mais ce n'est pas l'autorité finale sur de telles questions.
Décomposer le code en fonctions logiques est généralement une bonne idée, mais peu de programmeurs le font de la même manière que Martin: à un moment donné, la transformation de toutes les fonctions en fonctions diminue le rendement, et il peut être difficile de suivre lorsque tout le code est insuffisant. pièces.
Une option lorsqu'il ne vaut pas la peine de créer une toute nouvelle fonction consiste simplement à utiliser une variable intermédiaire:
Cela permet de garder le code facile à suivre sans avoir à parcourir le fichier beaucoup.
Un autre problème est que Clean Code est en train de devenir assez vieux comme livre. Beaucoup de génie logiciel a évolué dans le sens de la programmation fonctionnelle, alors que Martin fait tout son possible pour ajouter de l’état aux choses et créer des objets. Je pense qu'il aurait écrit un livre tout à fait différent s'il l'avait écrit aujourd'hui.
la source
Compte tenu du fait que la condition "est valide pour le courrier électronique" que vous avez actuellement accepterait l'adresse de courrier électronique très invalide "
@
", je pense que vous avez toutes les raisons de supprimer une classe EmailValidator. Mieux encore, utilisez une bonne bibliothèque bien testée pour valider les adresses électroniques.Les lignes de code en tant que métrique n'ont pas de sens. Les questions importantes en génie logiciel ne sont pas:
Les questions importantes sont:
Je n'ai jamais pensé à LoC lors de l'écriture de code pour une raison autre que Code Golf. Je me suis posé la question "Est-ce que je pourrais écrire ceci plus succinctement?"
Bien sûr, je pourrais peut-être utiliser une longue chaîne d'opérations booléennes au lieu d'une méthode utilitaire, mais devrais-je?
Votre question me fait penser à de longues chaînes de booléens que j'ai écrits et réalise que j'aurais probablement dû écrire une ou plusieurs méthodes d'utilité à la place.
la source
D'un côté, ils ont raison: moins de code, mieux c'est. Une autre réponse a cité Gate, je préfère:
En bref, moins vous avez de code, moins vous risquez de vous tromper. Si quelque chose n'est pas nécessaire, alors coupez-le.
Si le code est trop compliqué, simplifiez-le jusqu'à ce qu'il ne reste que les éléments fonctionnels.
Ce qui est important ici, c’est que tous se réfèrent à la fonctionnalité et ne disposent que du minimum requis pour le faire. Cela ne dit rien sur la façon dont cela s'exprime.
Ce que vous faites en essayant d’avoir un code propre n’est pas contre ce qui précède. Vous ajoutez à votre LOC mais n’ajoutez pas de fonctionnalités inutilisées.
L'objectif final est d'avoir un code lisible mais pas de suppléments superflus. Les deux principes ne doivent pas agir l'un contre l'autre.
Une métaphore serait de construire une voiture. La partie fonctionnelle du code est le châssis, le moteur, les roues ... ce qui fait fonctionner la voiture. La façon dont vous divisez cela ressemble plus à la suspension, à la direction assistée, etc., cela facilite la manipulation. Vous voulez que vos mécaniciens soient aussi simples que possible tout en effectuant leur travail, afin de minimiser les risques d'erreur, mais cela ne vous empêche pas d'avoir de belles places.
la source
Les réponses existantes comportent beaucoup de sagesse, mais j'aimerais ajouter un facteur supplémentaire: le langage .
Certaines langues utilisent plus de code que d'autres pour obtenir le même effet. En particulier, alors que Java (dont je soupçonne qu’il est le langage dans la question) est extrêmement bien connu et généralement très solide, clair et direct, certaines langues plus modernes sont beaucoup plus concises et expressives.
Par exemple, en Java, il peut facilement prendre 50 lignes pour écrire une nouvelle classe avec trois propriétés, chacune avec un getter et un setter, et un ou plusieurs constructeurs - alors que vous pouvez accomplir exactement la même chose en une seule ligne de Kotlin * ou Scala. (Économie encore plus si vous avez aussi voulu appropriés
equals()
,hashCode()
ettoString()
méthodes.)Le résultat est qu'en Java, ce travail supplémentaire signifie que vous êtes plus susceptible de réutiliser un objet général qui ne convient pas vraiment, de compresser des propriétés dans des objets existants ou de transmettre individuellement un ensemble de propriétés "nues"; alors que dans un langage concis et expressif, il est plus probable que vous écriviez un meilleur code.
(Cela met en évidence la différence entre la complexité 'superficielle' du code et la complexité des idées / modèles / traitements qu'il implémente. Les lignes de code ne sont pas une mauvaise mesure du premier, mais ont beaucoup moins à voir avec le second. .)
Donc, le «coût» de bien faire les choses dépend de la langue. Peut-être qu'un signe d'une bonne langue est un signe qui ne vous fait pas choisir entre bien faire les choses et les faire simplement!
(* Ce n'est pas vraiment l'endroit idéal pour un plug, mais Kotlin vaut bien un coup d'oeil à mon humble avis.)
la source
Supposons que vous travaillez avec la classe
Contact
actuellement. Le fait que vous écriviez une autre méthode pour valider l'adresse e-mail est la preuve que la classeContact
ne gère pas une seule responsabilité.Il gère également certaines responsabilités liées au courrier électronique, qui devraient idéalement constituer sa propre classe.
Une autre preuve que votre code est une fusion de
Contact
et deEmail
classe est que vous ne pourrez pas tester le code de validation du courrier électronique facilement. Il faudra beaucoup de manœuvres pour atteindre le code de validation de l’e-mail avec une grande méthode avec les bonnes valeurs. Voir la méthode à savoir ci-dessous.Par contre, si vous aviez une classe Email distincte avec une méthode de validation de l’e-mail, alors pour tester votre code de validation à l’unité, il vous suffirait de faire un simple appel
Email.Validation()
avec vos données de test.Contenu bonus: MFeather parle de la synergie profonde entre testabilité et bonne conception.
la source
Il a été démontré que la réduction de la LOC était corrélée à une réduction des défauts, rien d’autre. En supposant que chaque fois que vous réduisez le coût de possession, vous réduisez le risque de défauts, vous tombez essentiellement dans le piège consistant à croire que la corrélation est égale à la causalité. La LDC réduite est le résultat de bonnes pratiques de développement et non de ce qui fait la qualité du code.
D'après mon expérience, les personnes capables de résoudre un problème avec moins de code (au niveau macro) ont tendance à être plus compétentes que celles qui écrivent plus de code pour faire la même chose. Pour réduire le nombre de lignes de code, ces développeurs expérimentés utilisent / créent des abstractions et des solutions réutilisables pour résoudre les problèmes courants. Ils ne passent pas leur temps à compter des lignes de code et à se débattre pour savoir s'ils peuvent couper une ligne ici ou là. Souvent, le code qu'ils écrivent est plus détaillé que nécessaire, ils en écrivent moins.
Laisse moi te donner un exemple. J'ai dû composer avec la logique des périodes et de la manière dont elles se chevauchent, si elles sont adjacentes et quels écarts existent entre elles. Quand j'ai commencé à travailler sur ces problèmes, j'avais des blocs de code qui effectuaient les calculs partout. Finalement, j'ai construit des classes pour représenter les périodes et les opérations qui calculaient les chevauchements, les compléments, etc. Cela a immédiatement supprimé de grandes bandes de code et les a transformées en quelques appels de méthodes. Mais ces classes elles-mêmes n'étaient pas du tout réduites.
En termes clairs: si vous essayez de réduire le LOC en essayant de couper une ligne de code ici ou là avec plus de lacérations, vous le faites mal. C'est comme essayer de perdre du poids en réduisant la quantité de légumes que vous mangez. Écrivez un code facile à comprendre, à maintenir, à déboguer et à réduire le niveau de possession par la réutilisation et l’abstraction.
la source
Vous avez identifié un compromis valide
Il y a donc un compromis à faire ici, inhérent à l'abstraction dans son ensemble. Chaque fois que quelqu'un tente d'extraire N lignes de code dans sa propre fonction afin de le nommer et de l'isoler, il facilite simultanément la lecture du site appelant (en se référant à un nom plutôt qu'à tous les détails sanglants qui le sous-tendent) et plus complexe (vous avez maintenant une signification qui est enchevêtrée dans deux parties différentes de la base de code). "Facile" est l'opposé de "difficile", mais ce n'est pas un synonyme de "simple" qui est l'opposé de "complexe". Les deux ne sont pas opposés, et l'abstraction augmente toujours la complexité afin d'insérer une forme ou une autre de facilité.
Nous constatons directement la complexité accrue lorsqu'un changement dans les exigences de l'entreprise provoque la fuite de l'abstraction. Peut-être qu'une nouvelle logique serait allée plus naturellement au milieu du code pré-résumé, par exemple si le code abstrait traverse une arborescence et que vous souhaitez vraiment collecter (et éventuellement agir) une sorte d'informations pendant que vous êtes. traverser l'arbre. En attendant, si vous avez extrait ce code, il peut y avoir d'autres sites d'appels, et l'ajout de la logique requise au milieu de la méthode risque de casser ces autres sites d'appels. Vous voyez, chaque fois que nous modifions une ligne de code, il suffit de regarder le contexte immédiat de cette ligne de code; lorsque nous changeons une méthode, nous devons Cmd-F notre code source entier pour rechercher tout ce qui pourrait casser à la suite du changement de contrat de cette méthode,
L'algorithme glouton peut échouer dans ces cas
La complexité a également rendu le code, dans un certain sens, moins lisible que plus lisible.. Dans un travail précédent, je travaillais avec une API HTTP structurée de manière très précise et précise en plusieurs couches. Chaque point de terminaison est spécifié par un contrôleur qui valide la forme du message entrant, puis le transmet à un gestionnaire "couche de gestion". , qui a ensuite demandé à une "couche de données" qui était chargée de poser plusieurs requêtes à une couche "d'objet d'accès à des données", chargée de créer plusieurs délégués SQL qui répondraient effectivement à votre question. La première chose que je puisse dire à ce sujet a été que 90% du code était copié-collé, autrement dit qu’il s’agissait d’une solution simple. Ainsi, dans de nombreux cas, la lecture d’un passage de code était très "facile", car "oh ce gestionnaire ne fait que transmettre la demande à cet objet d’accès aux données".Beaucoup de changements de contexte, de recherche de fichiers et de suivi des informations que vous n'auriez jamais dû suivre ", cela s'appelle X sur cette couche, il s'appelle X 'sur cette autre couche, puis il s'appelle X' 'dans cette autre autre couche. "
Je pense que lorsque je me suis arrêté, cette simple API CRUD était au stade où, si vous l’imprimiez à 30 lignes par page, cela prendrait entre 10 et 20 manuels de cinq cents pages sur une étagère: c’était toute une encyclopédie de tâches répétitives. code. En termes de complexité essentielle, je ne suis pas sûr qu’il y ait même la moitié d’un manuel de complexité essentielle; nous n'avions peut-être que 5 ou 6 diagrammes de base de données pour le gérer. Effectuer un léger changement était une entreprise gigantesque, apprendre que c’était une entreprise gigantesque, ajouter de nouvelles fonctionnalités devenait tellement pénible que nous avions des fichiers de gabarit standard que nous utiliserions pour ajouter de nouvelles fonctionnalités.
J'ai donc constaté de première main comment rendre chaque partie très lisible et évident peut rendre le tout très illisible et non évident. Cela signifie que l'algorithme glouton peut échouer. Vous connaissez l'algorithme gourmand, oui? "Je ferai tout ce qui sera fait localement pour améliorer le plus la situation, et j'aurai ensuite confiance que je me trouve dans une situation globalement améliorée." Il s’agit souvent d’une belle première tentative mais elle peut aussi manquer dans des contextes complexes. Par exemple, dans le secteur de la fabrication, vous pouvez essayer d’accroître l’efficacité de chaque étape d’un processus de fabrication complexe - créez des lots plus volumineux, criez contre le public qui semble ne rien faire pour s’occuper de quelque chose d’autre - et cela peut souvent détruire l'efficacité globale du système.
Meilleure pratique: utilisez DRY et les longueurs pour effectuer l'appel
(Remarque: le titre de cette section est un peu une blague; je dis souvent à mes amis que quand quelqu'un dit "nous devrions faire X parce que les meilleures pratiques le disent bien ", 90% du temps, ils ne parlent pas de quelque chose comme une injection SQL ou un hachage de mot de passe ou quoi que ce soit - les meilleures pratiques unilatérales - et ainsi la déclaration peut être traduite dans 90% des cas, en "nous devrions faire X parce que je le dis ." Comme s'ils avaient peut-être un article de blog d'une entreprise qui avait fait un meilleur travail avec X plutôt qu'avec X ', mais rien ne garantit généralement que votre entreprise ressemble à cette entreprise. Il existe généralement un autre article provenant d'une autre entreprise qui a mieux fonctionné avec X' qu'avec X. Veuillez donc ne pas prendre le titre aussi. sérieusement.)
Ce que je recommanderais est basé sur une conférence de Jack Diederich intitulée Stop Writing Classes (youtube.com) . Il soulève plusieurs points intéressants dans cette discussion: par exemple, vous pouvez savoir qu'une classe n'est en réalité qu'une fonction lorsqu'elle ne comporte que deux méthodes publiques, dont le constructeur / initialiseur. Mais dans un cas, il parle de la façon dont une bibliothèque hypothétique dont la chaîne a été remplacée par "Muffin" a déclaré sa propre classe "MuffinHash" qui était une sous-classe du
dict
type intégré de Python. L'implémentation était totalement vide - quelqu'un venait de penser: "nous aurons peut-être besoin d'ajouter des fonctionnalités personnalisées aux dictionnaires Python plus tard, introduisons une abstraction maintenant, juste au cas où."Et sa réponse provocante était simplement: "nous pouvons toujours le faire plus tard, si nous en avons besoin."
Je pense que nous prétendons parfois que nous allons être de pires programmeurs dans le futur que nous ne le sommes actuellement, alors nous voudrons peut-être insérer une sorte de petite chose qui pourrait nous rendre heureux à l'avenir. Nous anticipons les besoins futurs. "Si le trafic est 100 fois plus important que prévu, cette approche ne sera pas adaptée, nous devons donc investir dès le départ dans cette approche plus dure qui sera adaptée." Très suspect.
Si nous prenons ce conseil au sérieux, nous devrons déterminer quand «plus tard» sera arrivé. La chose la plus évidente serait probablement d’établir une limite supérieure de la longueur des choses pour des raisons de style. Et je pense que le meilleur conseil qui reste serait d'utiliser DRY - ne vous répétez pas - avec ces heuristiques sur les longueurs de ligne pour corriger un trou dans les principes SOLID. Sur la base de l'heuristique de 30 lignes constituant une "page" de texte et une analogie avec la prose,
Comme je l’ai mentionné plus haut, j’ai testé ces statistiques sur l’arborescence source actuelle de Linux pour trouver ces pourcentages approximatifs, mais elles tiennent également lieu de raisonnement dans l’analogie littéraire.
la source