Pendant que nous programmons, nous développons tous des pratiques et des modèles que nous utilisons et sur lesquels nous nous appuyons. Cependant, au fil du temps, au fur et à mesure que notre compréhension, notre maturité et même notre utilisation de la technologie changent, nous nous rendons compte que certaines pratiques que nous pensions autrefois excellentes ne le sont pas (ou ne s'appliquent plus).
Un exemple d'une pratique que j'ai utilisée assez souvent, mais que j'ai changé ces dernières années, est l'utilisation du modèle d'objet Singleton .
Grâce à ma propre expérience et à de longs débats avec des collègues, je me suis rendu compte que les singletons ne sont pas toujours souhaitables - ils peuvent rendre les tests plus difficiles (en inhibant des techniques comme la moquerie) et peuvent créer un couplage indésirable entre les parties d'un système. Au lieu de cela, j'utilise maintenant des fabriques d'objets (généralement avec un conteneur IoC) qui cachent la nature et l'existence des singletons aux parties du système qui ne se soucient pas - ou ont besoin de savoir. Au lieu de cela, ils s'appuient sur une fabrique (ou un localisateur de services) pour accéder à ces objets.
Mes questions à la communauté, dans un esprit de développement personnel, sont:
- Quels modèles ou pratiques de programmation avez-vous reconsidérés récemment et essayez maintenant d'éviter?
- Par quoi avez-vous décidé de les remplacer?
la source
Points de retour uniques.
Une fois, j'ai préféré un point de retour unique pour chaque méthode, car avec cela, je pouvais m'assurer que tout nettoyage nécessaire à la routine n'était pas négligé.
Depuis lors, je suis passé à des routines beaucoup plus petites - donc la probabilité d'oublier le nettoyage est réduite et en fait le besoin de nettoyage est réduit - et je constate que les retours anticipés réduisent la complexité apparente (le niveau d'imbrication) du code. Les artefacts du point de retour unique - garder les variables de «résultat» autour, garder les variables d'indicateur, les clauses conditionnelles pour les situations non déjà faites - font que le code semble beaucoup plus complexe qu'il ne l'est en réalité, le rendent plus difficile à lire et à maintenir. Les sorties anticipées et les méthodes plus petites sont la voie à suivre.
la source
En un mot suringénierie .
la source
Notation hongroise (formes et systèmes). J'avais l'habitude de tout préfixer. strSomeString ou txtFoo. Maintenant, j'utilise someString et textBoxFoo. C'est beaucoup plus lisible et plus facile pour quelqu'un de nouveau de venir le chercher. En prime, il est trivial de le garder cohérent - camelCase le contrôle et ajoute un nom utile / descriptif. Les formulaires hongrois ont l'inconvénient de ne pas toujours être cohérents et les systèmes hongrois ne vous rapportent pas vraiment beaucoup. Le regroupement de toutes vos variables n'est pas vraiment utile - en particulier avec les IDE modernes.
la source
L'architecture "parfaite"
J'ai inventé L' architecture il y a quelques années. Je me suis techniquement poussé aussi loin que possible pour qu'il y ait des couches 100% faiblement couplées, une utilisation intensive des délégués et des objets légers. C'était le paradis technique.
Et c'était de la merde. La pureté technique de l'architecture a juste ralenti mon équipe de développement visant la perfection plutôt que les résultats et j'ai presque atteint un échec complet.
Nous avons maintenant une architecture beaucoup plus simple et moins techniquement parfaite et notre taux de livraison est monté en flèche.
la source
L'utilisation de la caféine. Une fois, cela m'a tenu éveillé et dans une ambiance de programmation glorieuse, où le code a volé de mes doigts avec une fluidité fébrile. Maintenant, ça ne fait rien, et si je ne l'ai pas, j'ai mal à la tête.
la source
Commenter le code. J'avais l'habitude de penser que le code était précieux et que vous ne pouvez pas simplement supprimer ces magnifiques joyaux que vous avez créés. Je supprime maintenant tout code commenté que je rencontre à moins qu'il n'y ait un TODO ou une NOTE attaché car il est trop périlleux de le laisser dedans. À savoir, j'ai rencontré de vieilles classes avec d'énormes parties commentées et cela m'a vraiment confus pourquoi ils étaient-ils: ont-ils été commentés récemment? est-ce un changement d'environnement de développement? pourquoi fait-il ce blocage sans rapport?
Envisagez sérieusement de ne pas commenter le code et de le supprimer à la place. Si vous en avez besoin, il est toujours sous contrôle de code source. YAGNI cependant.
la source
La surutilisation / abus des directives #region. C'est juste une petite chose, mais en C #, j'utilisais auparavant les directives #region partout, pour organiser mes classes. Par exemple, je regrouperais toutes les propriétés de classe dans une région.
Maintenant, je regarde l'ancien code et je suis surtout ennuyé par eux. Je ne pense pas que cela clarifie vraiment les choses la plupart du temps, et parfois ils vous ralentissent tout simplement. J'ai donc changé d'avis et je pense que les classes bien agencées sont pour la plupart plus propres sans directives régionales.
la source
Développement en cascade en général, et en particulier, la pratique d'écrire des spécifications fonctionnelles et de conception complètes et complètes qui devraient d'une manière ou d'une autre être canoniques, puis s'attendre à une mise en œuvre de celles-ci correcte et acceptable. Je l'ai vu remplacé par Scrum, et bon débarras, dis-je. Le fait est que la nature changeante des besoins et des désirs des clients rend toute spécification fixe effectivement inutile; la seule façon d'aborder vraiment correctement le problème est une approche itérative. Non pas que Scrum soit une solution miracle, bien sûr; Je l'ai vu mal utilisé et abusé de nombreuses fois. Mais ça bat la cascade.
la source
Jamais s'écraser.
Cela semble être une si bonne idée, n'est-ce pas? Les utilisateurs n'aiment pas les programmes qui plantent, alors écrivons des programmes qui ne plantent pas, et les utilisateurs devraient aimer le programme, non? C'est comme ça que j'ai commencé.
De nos jours, je suis plus enclin à penser que si ça ne marche pas, ça ne devrait pas prétendre que ça marche. Échouez dès que vous le pouvez, avec un bon message d'erreur. Si vous ne le faites pas, votre programme va planter encore plus fort quelques instructions plus tard, mais avec une erreur de pointeur nul non descriptive qui vous prendra une heure pour déboguer.
Mon modèle préféré "ne pas planter" est le suivant:
Maintenant, au lieu de demander à vos utilisateurs de copier / coller le message d'erreur et de vous l'envoyer, vous devrez plonger dans les journaux en essayant de trouver l'entrée de journal. (Et comme ils ont entré un ID utilisateur non valide, il n'y aura aucune entrée de journal.)
la source
null
ou la chaîne vide).J'ai pensé qu'il était logique d'appliquer des modèles de conception chaque fois que je les reconnaissais.
Je ne savais pas que je copiais en fait des styles à partir de langages de programmation étrangers, alors que le langage avec lequel je travaillais permettait des solutions beaucoup plus élégantes ou plus faciles.
L'utilisation de plusieurs langues (très) différentes m'a ouvert les yeux et m'a fait réaliser que je n'ai pas à mal appliquer les solutions des autres à des problèmes qui ne sont pas les miens. Maintenant, je frémis quand je vois le modèle d'usine appliqué dans un langage comme Ruby.
la source
Tests obsessionnels. J'étais un partisan enragé du développement test-first. Pour certains projets, cela a beaucoup de sens, mais j'en suis venu à réaliser qu'il est non seulement irréalisable, mais plutôt préjudiciable à de nombreux projets d'adhérer servilement à une doctrine d'écriture de tests unitaires pour chaque élément de fonctionnalité.
Vraiment, adhérer servilement à quoi que ce soit peut être préjudiciable.
la source
C'est une petite chose, mais: Se soucier de l'endroit où vont les accolades (sur la même ligne ou la ligne suivante?), Longueurs de ligne maximales suggérées pour le code, conventions de dénomination pour les variables et autres éléments de style. J'ai constaté que tout le monde semble se soucier plus de cela que moi, alors je suis simplement celui avec qui je travaille de nos jours.
Edit: L'exception à cela étant, bien sûr, quand je suis celui qui se soucie le plus (ou est celui qui est en mesure de définir le style d'un groupe). Dans ce cas, je fais ce que je veux!
(Notez que ce n'est pas la même chose que de ne pas avoir de style cohérent. Je pense qu'un style cohérent dans une base de code est très important pour la lisibilité.)
la source
La "pratique de programmation" la plus importante sur laquelle j'ai depuis changé d'avis est peut-être l'idée que mon code est meilleur que celui des autres. Ceci est courant pour les programmeurs (en particulier les débutants).
la source
Bibliothèques utilitaires. J'avais l'habitude de transporter un assemblage avec une variété de méthodes et de classes d'assistance avec la théorie que je pourrais les utiliser ailleurs un jour.
En réalité, je viens de créer un immense espace de noms avec beaucoup de fonctionnalités mal organisées.
Maintenant, je les laisse simplement dans le projet dans lequel je les ai créés. Selon toute probabilité, je n'en aurai pas besoin, et si je le fais, je pourrai toujours les refactoriser en quelque chose de réutilisable plus tard. Parfois, je les marque avec un // TODO pour une éventuelle extraction dans un assemblage commun.
la source
Concevoir plus que ce que j'ai codé. Au bout d'un moment, cela se transforme en paralysie d'analyse.
la source
L'utilisation d'un DataSet pour exécuter la logique métier. Cela lie le code trop étroitement à la base de données, et le DataSet est généralement créé à partir de SQL, ce qui rend les choses encore plus fragiles. Si le SQL ou la base de données change, il a tendance à se répercuter sur tout ce que le DataSet touche.
Exécution de toute logique métier à l'intérieur d'un constructeur d'objet. L'héritage et la capacité de créer des constructeurs surchargés ont tendance à rendre la maintenance difficile.
la source
Abréviation de la variable / méthode / table / ... Noms
J'avais l'habitude de faire cela tout le temps, même lorsque je travaillais dans des langues sans limites imposées sur la longueur des noms (enfin, ils étaient probablement 255 ou quelque chose). L'un des effets secondaires était un grand nombre de commentaires jonchant tout le code expliquant les abréviations (non standard). Et bien sûr, si les noms ont été modifiés pour une raison quelconque ...
Maintenant, je préfère de loin appeler les choses ce qu'elles sont vraiment, avec de bons noms descriptifs. y compris les abréviations standard uniquement. Pas besoin d'inclure des commentaires inutiles, et le code est beaucoup plus lisible et compréhensible.
la source
Foo(int arg0, String arg1, float arg2)
etcEnveloppant les composants d'accès aux données existants, comme la bibliothèque d'entreprise, avec une couche personnalisée de méthodes d'assistance.
la source
J'ai entendu parler pour la première fois de la programmation orientée objet en lisant sur Smalltalk en 1984, mais je n'avais pas accès à un langage oo jusqu'à ce que j'utilise le compilateur cfront C ++ en 1992. J'ai finalement pu utiliser Smalltalk en 1995. J'attendais avec impatience oo technologie, et a adhéré à l’idée qu’elle sauverait le développement de logiciels.
Maintenant, je vois simplement oo comme une technique qui présente certains avantages, mais ce n'est qu'un outil dans la boîte à outils. Je fais la plupart de mon travail en Python et j'écris souvent des fonctions autonomes qui ne sont pas des membres de classe, et je collecte souvent des groupes de données dans des tuples ou des listes où dans le passé j'aurais créé une classe. Je crée toujours des classes lorsque la structure des données est compliquée ou que j'ai besoin d'un comportement associé aux données, mais j'ai tendance à y résister.
Je suis en fait intéressé à faire du travail dans Clojure quand j'en aurai le temps, qui ne fournit pas de fonctionnalités oo, bien qu'il puisse utiliser des objets Java si je comprends bien. Je ne suis pas prêt à dire quelque chose comme oo est mort, mais personnellement, je ne suis pas le fan que j'étais.
la source
En C #, utilisation
_notation
pour les membres privés. Je pense maintenant que c'est moche.J'ai ensuite changé
this.notation
pour les membres privés, mais j'ai trouvé que je n'étais pas cohérent dans son utilisation, alors j'ai laissé tomber cela aussi.la source
this
ouMe
(respectivement C # et VB.NET) lors de l'appel de méthodes et de propriétés. IMO, cela rend mon code plus facile à lire et à comprendre plus tard, en particulier lorsqu'il y a quatre objets ou plus dans cette portée particulière.J'ai arrêté de suivre la méthode de conception recommandée par l'université avant la mise en œuvre. Travailler dans un système chaotique et complexe m'a obligé à changer d'attitude.
Bien sûr, je fais toujours des recherches sur le code, en particulier lorsque je suis sur le point de toucher du code que je n'ai jamais touché auparavant, mais normalement j'essaie de me concentrer sur des implémentations aussi petites que possible pour commencer quelque chose. C'est l'objectif principal. Ensuite, affinez progressivement la logique et laissez le design apparaître tout seul. La programmation est un processus itératif et fonctionne très bien avec une approche agile et avec beaucoup de refactoring.
Le code ne regardera pas du tout à quoi vous pensiez d'abord qu'il ressemblerait. Cela arrive à chaque fois :)
la source
J'étais passionné par la conception par contrat. Cela signifiait mettre beaucoup de vérification d'erreurs au début de toutes mes fonctions. Les contrats sont toujours importants, du point de vue de la séparation des préoccupations, mais plutôt que d'essayer d'imposer ce que mon code ne devrait pas faire, j'essaie d'utiliser des tests unitaires pour vérifier ce qu'il fait.
la source
J'utiliserais des statiques dans de nombreuses méthodes / classes car c'était plus concis. Quand j'ai commencé à écrire des tests, cette pratique a changé très rapidement.
la source
Exceptions vérifiées
Une idée étonnante sur papier - définit clairement le contrat, aucune possibilité d'erreur ou d'oubli de vérifier une condition d'exception. J'ai été vendu quand j'en ai entendu parler pour la première fois.
Bien sûr, cela s'est avéré être un tel désordre dans la pratique. Au point d'avoir des bibliothèques aujourd'hui comme Spring JDBC, qui a caché les exceptions vérifiées héritées comme l'une de ses principales fonctionnalités.
la source
Tout ce qui valait la peine n'était codé que dans une langue particulière. Dans mon cas, je pensais que C était le meilleur langage qui soit et je n'ai jamais eu aucune raison de coder quoi que ce soit dans une autre langue ... jamais.
Depuis, j'apprécie de nombreuses langues différentes et les avantages / fonctionnalités qu'elles offrent. Si je veux coder quelque chose de petit - rapidement - j'utiliserais Python. Si je veux travailler sur un grand projet, je coderais en C ++ ou C #. Si je veux développer une tumeur au cerveau, je coderais en Perl .
la source
Lorsque j'ai eu besoin de refactoriser, j'ai pensé qu'il était plus rapide et plus propre de commencer immédiatement et de mettre en œuvre le nouveau design, en réparant les connexions jusqu'à ce qu'elles fonctionnent. Ensuite, j'ai réalisé qu'il était préférable de faire une série de petites refactorisations pour progresser lentement mais sûrement vers le nouveau design.
la source
Peut-être que la chose la plus importante qui a changé dans mes pratiques de codage, ainsi que dans d'autres, est l'acceptation de classes extérieures et de bibliothèques téléchargées sur Internet comme base des comportements et des fonctionnalités des applications. À l'école, à l'époque où j'allais à l'université, nous étions encouragés à trouver comment améliorer les choses via notre propre code et à nous fier au langage pour résoudre nos problèmes. Avec les progrès dans tous les aspects de l'interface utilisateur et de la consommation de services / données, ce n'est plus une notion réaliste.
Il y a certaines choses qui ne changeront jamais dans une langue, et avoir une bibliothèque qui enveloppe ce code dans une transaction plus simple et en moins de lignes de code que je dois écrire est une bénédiction. La connexion à une base de données sera toujours la même. La sélection d'un élément dans le DOM ne changera pas. L'envoi d'un e-mail via un script côté serveur ne changera jamais. Avoir à écrire cette fois et encore gaspille du temps que je pourrais utiliser pour améliorer ma logique de base dans l'application.
la source
Initialisation de tous les membres de la classe.
J'avais l'habitude d'initialiser explicitement chaque membre de classe avec quelque chose, généralement NULL. J'en suis venu à réaliser que ceci:
la source
Comme vous, j'ai également adopté les modèles IoC pour réduire le couplage entre divers composants de mes applications. Cela simplifie grandement la maintenance et le remplacement des pièces, à condition que je puisse garder chaque composant aussi indépendant que possible. J'utilise également plus de cadres relationnels objet tels que NHibernate pour simplifier les tâches de gestion de base de données.
En un mot, j'utilise des "mini" frameworks pour aider à créer des logiciels plus rapidement et plus efficacement. Ces mini-frameworks permettent de gagner beaucoup de temps et, s'ils sont bien exécutés, peuvent rendre une application extrêmement simple à entretenir sur la route. Plug 'n Play pour la victoire!
la source