it-swarm.dev

Quelles «meilleures pratiques» populaires ne sont pas toujours les meilleures, et pourquoi?

Les "meilleures pratiques" sont partout dans notre industrie. A recherche Google sur les "meilleures pratiques de codage" donne près de 1,5 million de résultats. L'idée semble apporter du réconfort à beaucoup; suivez simplement les instructions, et tout se passera bien.

Quand je lis sur un meilleure pratique - par exemple, je viens d'en lire plusieurs dans Clean Code récemment - je deviens nerveux. Est-ce à dire que je devrais toujours utiliser cette pratique? Y a-t-il des conditions attachées? Y a-t-il des situations où cela pourrait pas être une bonne pratique? Comment savoir avec certitude jusqu'à ce que j'en apprenne davantage sur le problème?

Plusieurs des pratiques mentionnées dans Clean Code ne me convenaient pas, mais honnêtement, je ne sais pas si c'est parce qu'elles sont potentiellement mauvaises, ou si c'est juste mon parti pris personnel qui parle. Je sais que de nombreuses personnalités de l'industrie de la technologie semblent penser que il n'y a pas de meilleures pratiques , donc au moins mes doutes persistants me mettent en bonne compagnie.

Le nombre de meilleures pratiques que j'ai lues est tout simplement trop nombreux pour être énumérées ici ou poser des questions individuelles, je voudrais donc formuler ceci comme une question générale:

Quelles pratiques de codage couramment appelées "meilleures pratiques" peuvent être sous-optimales ou même nuisibles dans certaines circonstances? Quelles sont ces circonstances et pourquoi font-elles une mauvaise pratique?

Je préférerais entendre des exemples et des expériences spécifiques.

100
Steven Evers

Je pense que vous avez mis le doigt sur la tête avec cette déclaration

Je détesterais prendre les choses à leur valeur nominale et ne pas y penser de manière critique

J'ignore presque toutes les meilleures pratiques quand il ne vient pas avec une explication sur pourquoi il existe

Raymond Chen le met mieux dans cet article quand il dit

Les bons conseils sont accompagnés d'une justification afin que vous puissiez savoir quand ils deviennent de mauvais conseils. Si vous ne comprenez pas pourquoi quelque chose devrait être fait, alors vous êtes tombé dans le piège de la programmation culte du fret, et vous continuerez à le faire même quand ce n'est plus nécessaire ou devient même délétère.

125
Conrad Frix

Autant le jeter dans le ring:

Premature optimization is the root of all evil.

Non, ce n'est pas le cas.

Le devis complet:

"Nous devons oublier les petites efficacités, disons environ 97% du temps: l'optimisation prématurée est la racine de tout mal. Pourtant, nous ne devons pas laisser passer nos opportunités dans ces 3% critiques."

Cela signifie que vous profitez de améliorations spécifiques et stratégiques des performances tout au long de votre processus de conception. Cela signifie que vous utilisez des structures de données et des algorithmes qui sont cohérents avec les objectifs de performances. Cela signifie que vous êtes conscient des considérations de conception qui affectent les performances. Mais cela signifie également que vous n'optimisez pas frivolement lorsque cela vous donnera des gains mineurs au détriment de la maintenabilité.

Les applications doivent être bien architecturées, afin qu'elles ne tombent pas à la fin lorsque vous leur appliquez une petite charge, puis vous les réécrivez. Le danger avec la citation abrégée est que, trop souvent, les développeurs l'utilisent comme une excuse pour ne pas penser du tout aux performances jusqu'à la fin, quand il pourrait être trop tard pour faire quoi que ce soit. Il est préférable de créer de bonnes performances dès le départ, à condition de ne pas vous concentrer sur les minuties.

Supposons que vous construisez une application en temps réel sur un système embarqué. Vous choisissez Python comme langage de programmation, car "L'optimisation prématurée est la racine de tout mal." Maintenant, je n'ai rien contre Python, mais c'est est un langage interprété. Si la puissance de traitement est limitée, et qu'une certaine quantité de travail doit être effectuée en temps réel ou presque en temps réel, et que vous choisissez une langue qui nécessite plus de puissance de traitement pour le travail que vous n'en avez, vous êtes royalement vissé, car vous doivent maintenant recommencer avec une langue capable.

95
Robert Harvey

Un retour par fonction/méthode.

94
iMacUwhAK

Ne réinventez pas la roue est un dogme largement mal utilisé. Son idée est que si une solution appropriée existe, utilisez-la au lieu de créer la vôtre; en plus d'économiser des efforts, la solution existante est probablement mieux implémentée (sans bogue, efficace, testée) que ce que vous auriez initialement. Jusqu'ici tout va bien.

Le problème est qu'il existe rarement une solution 100% appropriée. Une solution appropriée à 80% pourrait exister, et son utilisation est probablement très bien. Mais qu'en est-il de 60%? 40%? Où tracez-vous la ligne? Si vous ne tracez pas la ligne, vous pourriez finir par incorporer une bibliothèque gonflée à votre projet parce que vous utilisez 10% de ses fonctionnalités - simplement parce que vous voulez éviter de "réinventer la roue".

Si vous réinventez la roue, vous obtiendrez exactement ce que vous voulez. Vous apprendrez également à fabriquer des roues. L'apprentissage par la pratique ne doit pas être sous-estimé. Et au final, une roue personnalisée pourrait bien être meilleure qu'une roue générique standard.

87
Joonas Pulakka

"Test unitaire de tout."

J'ai entendu dire souvent que tout le code devrait avoir des tests unitaires, un point avec lequel je ne suis pas d'accord. Lorsque vous testez une méthode, toute modification de la sortie ou de la structure de cette méthode doit être effectuée deux fois (une fois dans le code, une fois dans le test).

À ce titre, les tests unitaires devraient, à mon avis, être proportionnels à la stabilité structurelle du code. Si j'écris un système en couches de bas en haut, ma couche d'accès aux données aura des tests sur le wazoo; ma couche de logique métier sera assez bien testée, ma couche de présentation aura quelques tests et mes vues auront peu ou pas de test.

78
Fishtoaster

Toujours programme aux interfaces.

Parfois, il n'y aura qu'une seule implémentation. Si nous retardons le processus d'extraction d'une interface jusqu'au moment où nous en voyons le besoin, nous constaterons souvent que ce n'est pas nécessaire.

57
Eric Wilson

N'utilisez rien open-source (ou non-Microsoft pour vous les développeurs .NET)

Si Microsoft ne l'a pas développé, nous ne l'utilisons pas ici. Vous voulez utiliser ORM - EF, vous voulez utiliser IOC - Unity, vous voulez vous connecter - bloc d'application de journalisation d'entreprise. Il existe tellement de meilleures bibliothèques - mais je suis toujours bloqué dans le menu du dollar du monde du développement. Je jure que chaque fois que j'entends les meilleures pratiques de Microsoft, je pense que "McDonald's Nutritional Guidelines". Bien sûr, vous vivrez probablement si vous les suivez, mais vous serez également sous-alimenté et en surpoids.

  • Notez que ce n'est peut-être pas votre meilleure pratique, mais c'est une pratique courante suivie presque partout où j'ai travaillé.
46
Watson

Orientation objet

Il y a l'hypothèse, juste parce que le code est "orienté objet", c'est magiquement bon. Donc, les gens continuent de compresser les fonctionnalités dans les classes et les méthodes, juste pour être orientés objet.

40
LennyProgrammers

Tout le code doit être commenté.

Non, ça ne devrait pas l'être. Parfois, vous avez un code évident, par exemple les setters ne devraient pas être commentés, jusqu'à ce qu'ils fassent quelque chose de spécial. Aussi, pourquoi devrais-je commenter ceci:

/** hey you, if didn't get, it's logger. */
private static Logger logger = LoggerFactory.getLogger(MyClass.class);
35
Vladimir Ivanov

Méthodologies, en particulier Scrum. Je ne peux pas garder un visage impassible quand j'entends des adultes utiliser l'expression "Scrum Master". Je suis tellement fatigué d'entendre les développeurs protester qu'un certain aspect de la méthodologie X ne fonctionne pas pour leur entreprise, seulement pour être informé par Guru So-and-So que la raison pour laquelle cela ne fonctionne pas est qu'ils ne sont pas, en fait, de vrais pratiquants de la méthodologie X. "Scrum plus dur, vous devez, mon apprenant Padawan!"

Il y a des pépites de sagesse dans les méthodologies agiles --- beaucoup d'entre elles --- mais elles sont souvent contenues dans tellement de fumier que je ne peux pas combattre mon réflexe nauséeux. Prenez ce morceau de la page Scrum de Wikipedia :

Un certain nombre de rôles sont définis dans Scrum. Tous les rôles se répartissent en deux groupes distincts - porcs et poulets - en fonction de la nature de leur implication dans le processus de développement.

Vraiment? Porcs et poulets, dites-vous? Fascinant! J'ai hâte de présenter celui-ci à mon patron ...

32
evadeflow

Cartographie relationnelle des objets ... http://en.wikipedia.org/wiki/Object-relational_mapping

Je ne veux jamais être éloigné de mes données, ni perdre ce contrôle et cette optimisation précis. Mon expérience avec ces systèmes a été extrêmement médiocre ... Les requêtes générées par ces couches d'abstraction sont encore pires que ce que j'ai vu en délocalisation.

25
Fosco

Écriture des noms de fonction comme s'il s'agissait de phrases en anglais:

Draw_Foo()
Write_Foo()
Create_Foo()

etc. Cela peut sembler génial, mais c'est pénible lorsque vous apprenez une API. Est-il beaucoup plus facile de rechercher dans un index "Tout ce qui commence par Foo"?

Foo_Draw()
Foo_Write()
Foo_Create()

etc.

22
Colen

YAGNI

( Tu n'en auras pas besoin )

Cette approche m'a coûté des heures et des heures lorsque j'ai dû implémenter des fonctionnalités sur une base de code existante, où une planification minutieuse aurait inclus ces fonctionnalités au préalable.

Mes idées ont souvent été rejetées à cause de YAGNI, et la plupart du temps, quelqu'un devait payer pour cette décision plus tard.

(Bien sûr, on pourrait affirmer qu'une base de code bien conçue permettrait également d'ajouter des fonctionnalités plus tard, mais la réalité est différente)

22
Sean Patrick Floyd

MVC - Je trouve souvent que le transfert de nombreux problèmes de conception de sites Web dans l'approche MVC consiste davantage à rendre un cadre (Rails, etc.) heureux qu'à simplifier ou à structurer. MVC est un favori des "astronautes d'architecture" qui semblent privilégier l'échafaudage excessif sur la simplicité. ymmv.

basée sur la classe OO - à mon avis, encourage les structures complexes d'état mutable. les seuls cas convaincants que j'ai trouvés pour la classe OO au fil des ans sont les exemples ringards de "forme-> rectangle-> carré" qui forment le chapitre 1 de tout livre OO

22
Brad Clawsie

Pour SQL

  1. N'utilisez pas de déclencheurs
  2. Toujours masquer les tableaux derrière les vues

En ordre:

  1. Ils sont une fonctionnalité qui a sa place. Vous disposez de plusieurs chemins de mise à jour vers une table ou vous avez besoin d'un audit à 100%?

  2. Juste pourquoi? Je le ferais si je refactorisais pour maintenir un contrat, mais pas quand j'ai lu que les gens changent la vue pour correspondre aux changements de table

Éditer:

Numéro 3: éviter * avec EXISTS. Essayez 1/0. Ça marche. La liste des colonnes n'est pas évaluée selon la norme SQL. Page 191

20
gbn

Modèles de conception principalement. Ils sont surutilisés et sous-utilisés.

20
Geek

Le principe de responsabilité unique

("chaque classe ne devrait avoir qu'une seule responsabilité; en d'autres termes, chaque classe devrait en avoir une, et une seule, raison de changer")

Je ne suis pas d'accord. Je pense qu'une méthode ne devrait avoir qu'une seule raison de changer, et toutes les méthodes d'une classe devraient avoir un relation logique l'une avec l'autre , mais la classe elle-même pourrait en fait faites plusieurs choses (liées).

D'après mon expérience, ce principe est trop souvent appliqué avec trop de zèle et vous vous retrouvez avec de nombreuses petites classes à méthode unique. Les deux boutiques agiles dans lesquelles j'ai travaillé l'ont fait.

Imaginez si les créateurs de l'API .Net avaient eu ce genre de mentalité: plutôt que List.Sort (), List.Reverse (), List.Find () etc., nous aurions avoir des classes ListSorter, ListReverser et ListSearcher!

Plutôt que de ne plus argumenter contre le SRP (qui en soi n'est pas terrible en théorie), je vais partager quelques-unes de mes expériences anecdotiques de longue haleine:


À un endroit où j'ai travaillé, j'ai écrit un très simple solveur de flux max qui se composait de cinq classes: un nœud, un graphique, un créateur de graphe, un solveur de graphe et une classe pour utiliser le graphe -créateur/solveurs pour résoudre un problème du monde réel. Aucun n'était particulièrement complexe ou long (le solveur était de loin le plus long à ~ 150 lignes). Cependant, il a été décidé que les classes avaient trop de "responsabilités", alors mes collègues ont entrepris de refactoriser le code. Quand ils ont été faits, mes 5 classes ont été étendues à 25 classes, dont le total des lignes de code était plus du triple de ce qu'elles étaient à l'origine. Le flux du code n'était plus évident, ni le but des nouveaux tests unitaires; J'avais maintenant du mal à comprendre ce que faisait mon propre code.


Au même endroit, presque chaque classe n'avait qu'une seule méthode (sa seule "responsabilité"). Suivre le déroulement du programme était presque impossible, et la plupart des tests unitaires consistaient à tester que cette classe appelait le code de une autre classe, dont les deux objectifs étaient aussi un mystère pour moi. Il y avait littéralement des centaines de classes où il aurait dû y avoir (IMO) seulement des dizaines. Chaque classe n'a fait qu'une seule "chose", mais même avec des conventions de dénomination comme "AdminUserCreationAttemptorFactory", il était difficile de dire la relation entre les classes.


À un autre endroit (qui avait également la mentalité classes-devrait-avoir-seulement-une), nous essayions d'optimiser une méthode qui prenait 95% de temps pendant une certaine opération. Après (plutôt stupidement) l'optimiser un peu, j'ai tourné mon attention vers pourquoi on l'appelait un bajillion de fois. Il était appelé dans une boucle dans une classe ... dont la méthode était appelée dans une boucle dans une autre classe .. qui était également appelée dans une boucle ..

Tout compte fait, il y avait cinq niveaux de boucles réparties sur 13 classes (sérieusement). Ce qu'une classe faisait réellement était impossible à déterminer simplement en le regardant - vous deviez dessiner un graphique mental des méthodes qu'elle appelait, et quelles méthodes appelaient ces méthodes, et ainsi de suite. Si tout avait été regroupé en une seule méthode, cela n'aurait duré qu'environ 70 lignes avec notre méthode de problème imbriquée dans cinq niveaux de boucles immédiatement évidents.

Ma demande de refactoriser ces 13 classes en une seule classe a été refusée.

Maintenant que vous avez mentionné Clean Code, alors qu'il contient de bonnes idées, je pense que son obsession de refactoriser toutes les méthodes en sous-méthodes et celles en sous-méthodes, etc. est beaucoup trop loin. Au lieu de quelques méthodes à dix lignes, vous êtes censé préférer vingt lignes (soi-disant bien nommées). Évidemment, quelqu'un pense que c'est propre, mais cela me semble bien pire que la version originale.

En outre, le remplacement de simples éléments élémentaires tels que

0 == memberArray.length

au sein d'une classe avec un appel à la propre méthode de la classe telle que

isEmpty()

est une "amélioration" IMHO douteuse. Addition: La différence est que la première vérification fait exactement ce qu'elle dit: vérifie si la longueur du tableau est 0. Ok, isEmpty() pourrait également vérifier la longueur du tableau. Mais il pourrait également être implémenté comme ceci:

return null != memberArray ? 0 == memberArray.length : true;

Autrement dit, il comprend une vérification nulle implicite! Cela peut être un bon comportement pour une méthode publique - si le tableau est nul, alors quelque chose est certainement vide - mais lorsque nous parlons d'internes de classe, ce n'est pas si bien. Alors que l'encapsulation vers l'extérieur est un must, la classe internals doit savoir exactement ce qui se passe dans la classe. Vous ne pouvez pas encapsuler la classe d'elle-même . Explicite vaut mieux qu'implicite.


Cela ne veut pas dire que décomposer des méthodes longues ou des comparaisons logiques impliquées n'est pas bon; bien sûr que oui, mais dans quelle mesure le faire - où se trouve le sweet spot - est évidemment une question de goût. Décomposer une longue méthode entraîne plus de méthodes, et cela n'est pas gratuit. Vous devez sauter le code source pour voir ce qui se passe vraiment, quand vous pouvez le voir d'un coup d'œil si tout cela est dans une seule méthode.

J'irais même jusqu'à dire que dans certains cas une méthode à 1 ligne est trop courte pour mériter d'être une méthode.

14
Joonas Pulakka

"Soyez libéral avec des commentaires"

Les commentaires sont certainement une bonne chose, mais trop sont aussi mauvais, sinon pires qu'assez. Pourquoi? Eh bien, les gens ont tendance à ignorer les commentaires s'ils en voient trop. Je ne dis pas que vous pouvez avoir un code parfaitement auto-documenté, mais il est préférable de coder qui nécessite des commentaires pour une explication.

13
Jason Baker

GoTo considéré comme nuisible

Si vous implémentez une machine d'état, une instruction GOTO peut avoir plus de sens (lisibilité et code efficace) qu'une approche de "programmation structurée". Cela a vraiment inquiété certains collègues lorsque le premier morceau de code que j'ai écrit dans un nouveau travail comprenait non pas une mais plusieurs déclarations goto. Heureusement, ils étaient assez intelligents pour réaliser que c'était en fait la meilleure solution dans ce cas particulier.

Toute "meilleure pratique" qui ne permet pas d'exceptions raisonnables et documentées à ses règles est tout simplement effrayante.

12
MZB

Les sacrifices que nous faisons pour rendre le code testable

Je saute dans beaucoup de cerceaux pour rendre mon code testable, mais je ne prétends pas que je ne le ferais pas si on me donnait le choix. Cependant, j'entends souvent des gens pousser l'idée qu'il s'agit de "meilleures pratiques". Ces pratiques incluent (écrit dans la langue de .Net, mais s'applique également à d'autres langues):

  • Création d'une interface pour chaque classe. Ceci double le nombre de classes ( fichiers) à traiter et duplique le code. Oui, programmation d'interface est bon, mais c'est à cela que servent les spécificateurs publics/privés.
  • Chaque classe non instanciée au démarrage a besoin d'une fabrique. De toute évidence, new MyClass() est beaucoup plus simple que d'écrire une fabrique, mais maintenant la méthode qui crée, il ne peut pas être testé isolément. Sinon, je ne ferais que 1/20ème du nombre de classes d'usine que je fais maintenant.
  • Rendez chaque classe publique, , ce qui va à l'encontre du but d'avoir des spécificateurs d'accès aux classes. Cependant, les classes non publiques ne sont pas accessibles (et donc testées) à partir d'autres projets, donc la seule autre option est de déplacer tout le code de test vers le même projet (et donc de le publier avec le produit final).
  • Injection de dépendances. Il est clair que je dois donner chaque autre classe J'utilise un champ et un paramètre constructeur est beaucoup plus de travail que de les créer quand j'en ai besoin; mais je ne peux plus tester cette classe isolément.
  • Le principe de responsabilité unique, qui m'a causé tellement de maux de tête que je l'ai déplacé vers son réponse propre .

Alors, que pourrions-nous faire pour résoudre ce problème? Nous aurions besoin d'un changement radical dans l'architecture du langage:

  • Nous aurions besoin de la capacité de se moquer des classes
  • Nous aurions besoin de pouvoir tester des méthodes privées de classes internes, à partir d'un autre projet (cela peut sembler être une vulnérabilité de sécurité, mais je ne vois aucun problème si le candidat est obligé de nommer ses classes de testeurs) .
  • L'injection de dépendance (ou l'emplacement du service), ainsi que quelque chose d'équivalent à notre modèle d'usine existant, devrait être une partie core du langage.

En bref, nous avons besoin d'un langage conçu à partir de zéro avec la testabilité à l'esprit .

Séparation des applications en niveaux; couche de données, couche métier, couche UI

La principale raison pour laquelle je n'aime pas cela est que la plupart des endroits qui suivent cette méthode utilisent des cadres très fragiles pour le faire. C'EST À DIRE. UI Layer est codé à la main pour traiter les objets de la couche métier, les objets de la couche métier sont codés à la main pour traiter les règles métier et la base de données, la base de données est SQL et est déjà assez fragile et gérée par le groupe "DBA" qui n'aime pas le changement.

Pourquoi est-ce mauvais? La demande d'amélioration la plus courante est probablement "J'ai besoin d'un champ sur l'écran X qui a Y". Coup! Vous avez juste une nouvelle fonctionnalité qui affecte chaque couche unique, et si vous séparez des couches avec différents programmeurs, c'est devenu un gros problème impliquant plusieurs personnes et groupes, pour un changement très simple.

De plus, je ne sais pas combien de fois j'ai été dans des arguments qui vont quelque chose comme ça. "Le champ de nom est limité à une longueur maximale de 30, s'agit-il d'une couche d'interface utilisateur, d'une couche métier ou d'un problème de couche de données?" Et il y a cent arguments, et pas de bonne réponse. La réponse est la même, elle affecte toutes les couches, vous ne voulez pas rendre l'interface utilisateur stupide et devez passer par toutes les couches, et échouer dans la base de données, juste pour que l'utilisateur découvre que son entrée est trop longue. Si vous le changez, cela affecte tous les calques, etc.

Les "couches" ont également tendance à fuir; Si une couche est physiquement séparée par des limites de processus/machine (interface utilisateur Web IE et logique de backend métier), les règles sont dupliquées pour que tout fonctionne raisonnablement bien. C'est à dire. une certaine logique métier se retrouve dans l'interface utilisateur, même s'il s'agit d'une "règle métier", car l'utilisateur a besoin que l'interface utilisateur soit réactive.

Si le cadre utilisé, ou l'architecture utilisée, résiste aux petits changements et aux fuites, c'est-à-dire sur la base de métadonnées, et est ajusté dynamiquement à travers toutes les couches, cela peut être moins douloureux. Mais la plupart des frameworks sont une douleur royale, nécessitant des changements d'interface utilisateur, des changements de couche métier et des modifications de base de données, pour chaque petit changement, et entraînant plus de travail et moins d'aide que la technique n'est censée produire.

Je serai probablement critiqué pour cela, mais ça y est :)

10
Jay

JavaBeans

L'utilisation de JavaBeans en Java. Voir ma question Pourquoi ne devrais-je pas utiliser des POJO immuables au lieu de JavaBeans? sur StackOverflow.

9
Jonas

Histoires d'utilisateurs/Cas d'utilisation/Personnages

Je comprends la nécessité de ceux-ci lorsque vous programmez pour une industrie que vous ne connaissez pas, mais je pense que lorsqu'ils sont mis en œuvre pleinement, ils deviennent trop corporatifs et deviennent une perte de temps.

7
riwalk

80 limites de caractères/ligne sont stupides

Je comprends que certains compromis doivent être faits pour correspondre au rythme du coureur le plus lent du côté de l'interface graphique (limitations de résolution d'écran, etc.) mais, pourquoi cette règle s'applique-t-elle au formatage du code?

Voir ... Il y avait cette petite invention appelée la barre de défilement horizontale qui a été créée pour gérer l'espace d'écran virtuel en dehors de la limite de pixels la plus à droite. Pourquoi les développeurs, qui ont réussi à créer d'excellents outils d'amélioration de la productivité comme la mise en évidence de la syntaxe et la saisie semi-automatique, ne l'utilisent-ils pas?

Bien sûr, il existe des éditeurs CLI religieusement utilisés par les dinosaures * nix qui suivent les anciennes limitations fatiguées de leurs terminaux VT220, mais pourquoi sommes-nous tenus au même standard?

Je dis, vissez la limite de 80 caractères. Si les dinosaures sont suffisamment épiques pour pirater emacs/vim toute la journée, pourquoi ne devrait-il pas être capable de créer une extension qui enveloppe automatiquement les lignes ou offre des capacités de défilement horizontal à leurs IDE CLI?

Les moniteurs 1920x1080 pixels deviendront finalement la norme et les développeurs du monde entier vivent toujours sous les mêmes limites sans aucune raison pour laquelle ils le font sauf, c'est ce que leurs aînés leur ont dit de faire lorsqu'ils commençaient à peine à programmer.

Les limites de 80 caractères sont pas une meilleure pratique mais une pratique de niche pour une très minorité de programmeurs et doivent être traitées comme telles.

Modifier:

Il est compréhensible que de nombreux développeurs n'aiment pas la barre de défilement horizontale car elle nécessite un geste de la souris, alors ... Pourquoi ne pas augmenter la limite de largeur de colonne à un nombre plus élevé (que 80) pour ceux d'entre nous qui utilisent des écrans modernes.

Lorsque les écrans d'ordinateur 800x600 sont devenus la norme pour la plupart des utilisateurs, les développeurs Web ont augmenté la largeur de leur site Web pour accueillir la majorité ... Pourquoi les développeurs ne peuvent-ils pas faire de même?.

7
Evan Plaice

Mesurer, mesurer, mesurer

Si bien, mesurez loin, mais pour isoler bogues de performance, la mesure fonctionne aussi bien que l'élimination successive. Voici la méthode que j'utilise.

J'ai essayé de retrouver la source de la "sagesse" mesure-mesure. Quelqu'un avec une caisse à savon assez grande l'a dit, et maintenant il voyage.

5
Mike Dunlavey

Utiliser des singletons

Quand vous ne devriez avoir qu'une seule instance de quelque chose. Je ne peux pas en désaccord plus. N'utilisez jamais un singleton et allouez-le une seule fois et passez le pointeur/objet/référence si nécessaire. Il n'y a absolument aucune raison de ne pas le faire.

5
user2528

Mon professeur exige que je commence tous mes identifiants (sans compter les constantes) avec des lettres minuscules, par ex. myVariable.

Je sais que cela semble être une chose mineure, mais de nombreux langages de programmation nécessitent variables pour commencer par des lettres majuscules. J'apprécie la cohérence, c'est donc une de mes habitudes de tout commencer par des lettres majuscules.

5
Maxpm

en utilisant int non signé comme itérateur

Quand apprendront-ils que l'utilisation de int signé est beaucoup plus sûre et moins sujette aux bogues. Pourquoi est-il si important que l'index du tableau ne puisse être qu'un nombre positif, que tout le monde soit content d'ignorer le fait que 4 - 5 est 4294967295?

5
AareP

Les méthodes ne doivent pas dépasser un seul écran

Je suis entièrement d'accord avec le principe de la responsabilité unique, mais pourquoi les gens le perçoivent-ils comme signifiant "une fonction/méthode ne peut avoir qu'une seule responsabilité au plus haut niveau de granularité logique"?

L'idée est simple. Une fonction/méthode doit accomplir une tâche. Si une partie de cette fonction/méthode peut être utilisée ailleurs, découpez-la dans sa propre fonction/méthode. S'il peut être utilisé ailleurs sur le projet, déplacez-le dans sa propre classe ou une classe utilitaire et rendez-le accessible en interne.

Avoir une classe qui contient 27 méthodes d'assistance qui ne sont appelées qu'une seule fois dans le code est stupide, un gaspillage d'espace, une augmentation inutile de la complexité et un temps considérable. Cela ressemble plus à une bonne règle pour les personnes qui veulent regarder du code de refactorisation occupé mais ne produisent pas beaucoup.

Voici ma règle ...

Écrire des fonctions/méthodes pour accomplir quelque chose

Si vous vous trouvez sur le point de copier/coller du code, demandez-vous s'il serait préférable de créer une fonction/méthode pour ce code. Si une fonction/méthode n'est appelée qu'une seule fois dans une autre fonction/méthode, y a-t-il vraiment un intérêt à l'avoir en premier lieu (sera-t-elle appelée plus souvent à l'avenir). Est-il utile d'ajouter plus de sauts dans/hors des fonctions/méthodes pendant le débogage (c'est-à-dire, le saut ajouté rend-il le débogage plus facile ou plus difficile)?

Je suis tout à fait d'accord pour dire que les fonctions/méthodes supérieures à 200 lignes doivent être examinées attentivement, mais certaines fonctions n'accomplissent qu'une seule tâche sur autant de lignes et ne contiennent aucune partie utile pouvant être résumée/utilisée dans le reste du projet.

Je le regarde du point de vue d'un développeur d'API ... Si un nouvel utilisateur regardait le diagramme de classe de votre code, combien de parties de ce diagramme auraient du sens dans l'ensemble du projet et combien existeraient uniquement en tant que aides à d'autres parties internes au projet.

Si je devais choisir entre deux programmeurs: le premier a tendance à écrire des fonctions/méthodes qui essaient d'en faire trop; la seconde casse chaque partie de chaque fonction/méthode au plus haut niveau de granularité; Je choisirais les premières mains. Le premier accomplirait plus (c.-à-d., Rédigerait plus de viande de l'application), son code serait plus facile à déboguer (en raison de moins de sauts de fonctions/méthodes pendant le débogage), et il perdrait moins de temps à faire un travail occupé à perfectionner la façon dont le code ressemble vs perfectionner la façon dont le code fonctionne.

Limitez les abstractions inutiles et ne polluez pas la saisie semi-automatique.

4
Evan Plaice

Absolutiste, strict, encapsulation

Je suis principalement d'accord avec l'encapsulation, mais ce fut un véritable libérateur de briser temporairement cette règle afin de convertir du code procédural en OOP en utilisant Refactoring de tableau en objet . ( J'avais besoin d'un coup de pouce pour me détendre un peu. Merci, Martin Fowler)

  • Array

    ->

  • nouvelle classe avec tableau comme propriété publique

    ->

  • passer par le code client/ajouter des accesseurs

    ->

  • seulement alors l'encapsuler et le rendre privé/protégé

2
JW01

Sur la généralisation.

Le bloc carré ne rentre PAS dans le trou du cercle!

1
PMV

La seule chose à laquelle je pense est le formatage des instructions Java if comme ceci:

if (condition) ...

au lieu de

if(condition) ...

Pour la plupart, j'ai trouvé que les meilleures pratiques sont les meilleures, et toutes les réserves initiales que j'ai avec elles ont tendance à être mal placées ou remplacées par des préoccupations plus importantes.

1
Armand

"Si ce n'est pas cassé, ne le répare pas". Le code est toujours cassé. La raison pour laquelle personne ne dit au développeur d'origine est qu'il

  1. pense que c'est leur faute,
  2. ne sais pas qui contacter,
  3. ne peut pas obtenir de l'aide pour parler avec un "technicien",
  4. ne peut pas être dérangé, ou
  5. je ne sais pas comment décrire le problème avec suffisamment de détails.
1
l0b0

Toujours privilégier les noms longs, explicites, variables et de routine par rapport à la forme abrégée

par exemple, privilégiant Authentification sur AuthN

Cela m'a mord , lorsque les chemins de fichiers MS sont devenus si longs que ma copie de travail Subversion n'a pas pu se charger sur mon PC.

Voir: https://stackoverflow.com/questions/3282303/my-choice-of-class-names-is-hampered-by-windows-xp-max-path-length-issues-with-sv

1
JW01

J'ai tendance à ignorer presque toutes les meilleures pratiques lorsque je fais un projet relativement petit et ponctuel, comme l'écriture d'un analyseur requis pour migrer des fichiers. Lorsque tout ce dont j'ai besoin est le résultat, une fois, je me fiche de la lisibilité, de l'évolutivité, de la maintenabilité, etc.

1
user281377

Le filetage est la réponse à tous les problèmes de performances

En désaccord avec cela pour de nombreuses raisons.

  • En général, l'indexation et la mise en cache temporelle augmentent considérablement les performances. Bien sûr, vous devrez peut-être utiliser des "drapeaux sales".

  • Les problèmes qui découlent de l'embonpoint multi-threading bénéficient tous du temps et de l'argent.

  • Ce que la technologie multicœur nous a vraiment apporté, c'est une meilleure multitâche (exécuter deux applications aussi rapidement qu'une). L'utilisation de programmes multithreading habilement écrits n'est qu'un effet secondaire.

0
AareP

CONTINUER LA DÉCLARATION IS MAUVAIS

Je vais faire référence aux normes de codage C++ du Joint Strike Fighter Air Vehicle ici:

Règle AV 190 (Règle MISRA 57) L'instruction continue ne doit pas doit être utilisée.

et un de mes professeurs:

"LA DÉCLARATION CONTINUE IS MAUVAIS"

Leur logique est qu'elle perturbe le flux de contrôle et rend le code moins lisible. L'utilisation des instructions imbriquées if est une approche plus propre.

Pourtant, je trouve cela plus lisible:

 
for(int i = 0; i < CONST_FOO; ++i) {
    if(aTwo[i] == NULL) continue;
    aTwo[i]->DoBar();
    //...do other stuff with aTwo[i]
    //...do other stuff with aTwo[i]
    //...do other stuff with aTwo[i]
    //...do other stuff with aTwo[i]
    //...do other stuff with aTwo[i]
    //...do other stuff with aTwo[i]
    //...do other stuff with aTwo[i]
    //...do other stuff with aTwo[i]
}
 

Que ceci:

 
for(int i = 0; i < CONST_FOO; ++i) {
    if(aTwo[i] != NULL) {
        aTwo[i]->DoBar();
        //...do other stuff with aTwo[i]
        //...do other stuff with aTwo[i]
        //...do other stuff with aTwo[i]
        //...do other stuff with aTwo[i]
        //...do other stuff with aTwo[i]
        //...do other stuff with aTwo[i]
        //...do other stuff with aTwo[i]
        //...do other stuff with aTwo[i]
        //...do other stuff with aTwo[i]
        //...do other stuff with aTwo[i]
        //...do other stuff with aTwo[i]
    }
}
 

Il s'agit d'un exemple très simpliste (imaginez que les if imbriqués dépassent de beaucoup le niveau), mais il est similaire à la "meilleure" pratique ridicule "une seule déclaration de retour par fonction". Il empêche le débogueur de sauter (peut-être à plusieurs pages de distance), moins l'indentation rend généralement le code facilement lisible, etc.

0
Casey

En JavaScript, beaucoup de gens considèrent qu'il est préférable d'écrire tous les points-virgules dont ils auraient besoin dans d'autres langages de branche C (et beaucoup d'entre eux n'ont pas peur de signaler l '"erreur" chaque fois qu'ils voient du code qui pourrait avoir plus de points-virgules). Je n'en ai jamais trouvé le besoin, leur rôle de marqueur visuel est déjà rempli par des décalages de ligne.

Sur une note latérale, il est un peu drôle de voir un compilateur nécessitant des points-virgules, mais toujours jeter en toute confiance l'erreur "Point-virgule manquant". "Nous savons tous les deux ce que vous vouliez écrire, mais je dois rejeter votre candidature parce que je n'ai formellement pas le droit de faire la distinction entre les espaces et les changements de ligne."

Un certain nombre d'autres bonnes pratiques de style JavaScript/C circulent, mais aucune ne se rapproche en termes de battage médiatique sans arguments qualifiés.

Edit: Il est parfaitement possible de réduire le code sans point-virgule Compilateur de fermeture les insérera au besoin.

0
aaaaaaaaaaaa

Eh bien, l'un de mes boutons chauds est analyse des performances . Les gens disent

L'optimisation prématurée est la racine de tout Mal.

Et puis ils disent que la citation complète est:

Il faut oublier les petites efficacités, disons environ 97% du temps: l'optimisation prématurée est la racine de tout mal. Pourtant, nous ne devons pas laisser passer nos opportunités dans ces 3% critiques.

Ce qui est parfaitement logique lorsque vous discutez des "algorithmes" - des trucs académiques intelligents où 3% du programme pourraient être deux lignes de code.

Je travaille dans 10 ^ 6 applications en ligne, avec 10 ^ 5 méthodes dans 10 ^ 4 classes, travaillées au fil des ans par une douzaine de programmeurs et testeurs, subissant de nombreuses révisions et versions, où cette citation n'a aucune pertinence. Généralement, les drains temporels sont des lignes de code uniques qui peuvent être des "opportunités", mais personne ne pourrait jamais deviner où elles se trouvent.

OTOH, les gens disent "profil", ou ils disent "mesure mesure". Bien. Ils le disent, mais ils ne le font PAS souvent. Cela pourrait être la raison pour laquelle ils ne le font pas cela ne fonctionne pas très bien .

Cette réponse en dit plus à ce sujet, et souligne ce qui fonctionne .

0
Mike Dunlavey

Liaison de données

Je le déteste et je l'adore. (Dépend de la complexité du projet)

0
Amir Rezaei