Techniques de programmation surutilisées ou abusées [fermé]

38

Y a-t-il des techniques de programmation que vous trouvez trop utilisées (IE beaucoup plus que ce qu’elles devraient être) ou mal utilisées, ou utilisées un peu pour tout, sans être une très bonne solution à de nombreux problèmes que l’on essaie de résoudre? résoudre avec elle.

Cela peut être des expressions régulières, une sorte de motif de conception ou peut-être un algorithme, ou quelque chose de complètement différent. Vous pensez peut-être que les gens abusent de l'héritage multiple, etc.

Anto
la source
33
Je conviens que IE est utilisé de manière beaucoup plus excessive qu'il ne le devrait, mais c'est principalement par des non-programmeurs. . .
Eric Wilson
7
@FarmBoy - Je pense qu'il voulait dire IE: "Ie" signifie simplement "c'est-à-dire", ce qui est entièrement écrit en latin est "id est".
Raphaël
Corrigé maintenant :)
Anto
4
Toute technique peut (et est souvent mal utilisée), il suffit de la présenter comme la prochaine solution miracle et vous trouverez quelqu'un qui traite chaque problème comme un clou (pour mélanger les métaphores).
ChrisF
8
@Rapheal - Je plaisantais, bien sûr. Merci pour l'éducation.
Eric Wilson

Réponses:

73

Commentaires dans le code

J'espère que les professeurs d'université comprendront qu'ils n'ont pas besoin d'apprendre à leurs étudiants à écrire 10 lignes de commentaires indiquant que le code suivant est une boucle for, en effectuant une itération de 1 à un nombre de x. Je peux le voir dans le code!

Apprenez-leur à rédiger un code auto-documenté en premier lieu, puis des commentaires appropriés sur ce qui ne peut pas être ensuite auto-documenté de manière adéquate. Le monde du logiciel serait un meilleur endroit.

Dan McGrath
la source
26
Le code auto-documenté n'est pas. Les professeurs le font également pour apprendre aux étudiants à conceptualiser le problème et à l’approcher. De plus, je n'ai jamais vu personne se plaindre de trop de documentation. Attention, la documentation est correcte.
Woot4Moo
24
@ Woot4Moo: si vous lisez Clean Code, Fowler indique clairement qu'une documentation obsolète est pire qu'une absence de documentation et que tous les commentaires ont tendance à devenir obsolètes et à migrer hors du code qu'ils documentent. Tout ce livre explique comment écrire du code auto-documenté.
Scott Whitlock
12
Leur apprendre
15
+1 En réalité, j'ai observé ce qui suit dans le code du monde réel: "loopVar ++; // increment loopVar". AAAAAAAAAAAAARARRRRRGH!
Tables Bobby
7
@ Bill: À mon avis, vous ne devriez pas avoir à documenter la logique générique et les structures de contrôle, même si elles sont relativement complexes. Fondamentalement, tout commentaire qu'un bon développeur connaissant le langage devrait pouvoir analyser en analysant le code ne devrait pas être commenté. par exemple. Un ensemble de boucles for imbriquées avec des ruptures à l'intérieur, etc. Mais ce qui DEVRAIT être commenté est le raisonnement spécifique à l'application qui explique pourquoi le code prend ces décisions: par exemple. "Si un nouveau programmeur commence dans l'entreprise demain et examine le code, cela aura-t-il un sens sans les indications de commentaires?"
Tables Bobby
57

Le modèle de conception singleton.

C'est un modèle utile, mais chaque fois qu'un nouveau programmeur découvre ce modèle, il commence à essayer de l'appliquer à chaque classe qu'il crée.

Raphael
la source
J'utilise cette excuse mal conçue pour un cadre de travail tous les jours. codeigniter.com/user_guide/libraries/email.html Ils pensent que la POO préfixe les fonctions $this->. PHP est un langage pourri, je ne peux donc pas m'attendre à ce que les cadres soient excellents.
Keyo
7
Je pense que tout programmeur qui implémente un singleton et ne se repent pas brûlera dans un enfer ardent pour le (s) péché (s) qu'il / elle a commis.
2
J'ai implémenté un singleton une fois dans ma carrière professionnelle (dans un contexte multitâche) et je devais me repentir de mon péché en le réécrivant.
Spoike
3
Les singletons peuvent être utiles pour quelques choses, mais sont presque toujours utilisés quand ils ne devraient pas l'être. Cela ne signifie pas que les singletons ne doivent jamais être utilisés - ce n'est pas parce que quelque chose est maltraité qu'ils ne peuvent pas être utilisés correctement.
configurateur
2
@Rapahel: C'est exactement pourquoi je ne crois pas que l'étude des modèles de conception soit une bonne chose.
configurateur
53

La chose la plus diabolique pour protéger la programmation muette. tout mettre dans une prise d'essai et ne rien faire avec la prise

        try
        {
            int total = 1;
            int avg = 0;
            var answer = total/avg;
        }
        catch (Exception)
        {

        }

Je frémis quand je vois un essai qui ne fait rien et qui est conçu pour gérer une logique idiote. En général, les captures sont trop utilisées, mais dans certains cas, elles sont très utiles.

Nickz
la source
4
Drôle, je viens d’éditer un fichier qui le fait des centaines de fois, et avec raison. Il s’agit d’un fichier de test unitaire, testant que différentes méthodes génèrent une exception lorsque cela est prévu. Le bloc try contient un appel et un rapport "Le lancement attendu n'a pas eu lieu". L'exception est attendue et correcte, il n'y a donc pas d'action corrective. De toute évidence, les tests unitaires sont un cas particulier, mais j'ai eu des cas similaires dans le code réel. Drapeau rouge, oui, mais pas une règle absolue.
Steve314
5
@Steve le cas que vous avez décrit est une condition de bord rare. Un autre exemple auquel je peux penser est celui de la journalisation du code. Si la journalisation échoue, il est inutile d’essayer de consigner l’exception ou d’interrompre l’application.
dbkk
1
@dbkk - convenu de la condition des bords, et j'ajouterais que lorsque vous avez vraiment besoin d'attraper une exception mais n'avez pas besoin d'action corrective, ajoutez un commentaire dans le bloc catch pour expliquer ce qui est essentiel, ne serait-ce que pour calmer le mainteneurs. Ce n'est pas si rare dans les tests unitaires, alors je laisserais tomber le commentaire dans ce cas.
Steve314
5
en cas d'erreur, reprise suivante
jk.
2
@ jk01 - une exception n'est pas (nécessairement) une erreur. Le fait qu'une condition soit une erreur ou non dépend du contexte. Par exemple, "fichier non trouvé" n'est pas une erreur si vous n'avez pas besoin du fichier. C’est peut-être juste un fichier de paramètres facultatif qui peut ne pas être présent, et vous pouvez simplement laisser vos valeurs par défaut si le fichier n’est pas là (aucune action corrective n’est donc nécessaire après la capture).
Steve314
47

Comptez sur StackOverflow pour résoudre vos problèmes au lieu de le résoudre à la dure.

Les nouveaux programmeurs qui découvrent (trop souvent) la richesse des connaissances sur SO postent avant de penser et d’essayer des choses.

De mon temps, nous devions coder à partir de livres, pas d'internet, pas de SO. Maintenant sortez de ma pelouse.

Byron Whitlock
la source
28
Je dois admettre que je crains l'audace de certaines questions sur SO. Soit parce qu'on leur pose la question plusieurs fois par jour et qu'ils n'ont manifestement pas cherché du tout; ou pire encore, ils traitent la communauté comme un service d’externalisation gratuit.
Orbling
2
@dbkk: stackoverflow.com/questions/4665778/… -> premier commentaire "avez-vous déjà essayé cela?"
Matthieu M.
5
J'ai commencé à apprendre à partir de livres, mais une fois les bases acquises, j'ai presque tout appris grâce aux discussions en ligne. Pas en demandant, mais principalement (et au début, exclusivement) en lisant. Cette méthode m'a appris plusieurs langages de programmation dans une profondeur insoutenable (avec beaucoup de recoins), et je pense que ce n'est pas une mauvaise méthode du tout.
Konrad Rudolph
1
@ Konrad Rudolph: Cette méthode est bonne et sage, lire des questions, bien chercher. Le mieux est de poser la question lorsque le demandeur dispose d’un cadre lui permettant de comprendre les réponses. Trop souvent, les gens posent des questions qu’ils n’ont pas (encore) la capacité de comprendre.
Orbling le
3
Le problème, c’est que SO l’encourage en donnant beaucoup de repères pour poser / répondre à des questions très simples auxquelles il est possible de répondre avec une simple recherche google. question très difficile, les gens répondent uniquement parce qu’ils le veulent vraiment.
IAdapter
36

OOP évidemment. C'est très utile, mais quand on l'utilise mal, cela peut assez facilement obscurcir un code autrement clair (on peut penser à quelques exemples de programmation S4 en R), et peut engendrer une surcharge énorme inutile et qui peut vous faire perdre beaucoup de temps en performances.

Une autre chose est que (dans Perl, par exemple) OOP revient souvent à écrire la même chose dans l’inverse: result = $object ->function(pars)au lieu de result = function(object, pars)Cela a parfois un sens, mais mélangé à une programmation procédurale, la lecture du code peut être assez déroutante. Et en dehors de cela, vous introduisez simplement plus de frais généraux là où cela n'améliore pas la conception. Cela revient aussi à ce qui est dit à propos du motif singleton: devrait être utilisé, mais pas sur tout.

J'utilise moi-même la programmation orientée objet, mais dans mon domaine (calcul scientifique), les performances sont un gros problème, et la programmation orientée objet y est souvent utilisée de manière abusive, car tous les étudiants acquièrent Java de nos jours. C'est génial pour traiter de gros problèmes, pour conceptualiser et ainsi de suite. Mais si vous travaillez avec des séquences d’ADN dans BioPerl, par exemple, l’utilisation systématique des objets et l’utilisation systématique de getters et de setters peuvent décupler le temps de calcul. Lorsque votre code est exécuté quelques jours au lieu de quelques heures, cette différence est primordiale.

Joris Meys
la source
6
@Craige: J'utilise moi-même la programmation orientée objet, mais dans mon domaine (calcul scientifique), les performances sont un gros problème, et la programmation orientée objet y est souvent utilisée de manière abusive, car tous les étudiants acquièrent Java de nos jours. C'est génial pour traiter de gros problèmes, pour conceptualiser et ainsi de suite. Mais si vous travaillez avec des séquences d’ADN dans BioPerl, par exemple, l’utilisation systématique des objets et l’utilisation systématique de getters et de setters peuvent décupler le temps de calcul. Lorsque votre code est en cours d' exécution quelques jours au lieu de quelques heures, cette différence vraiment compte.
Joris Meys
1
@Craige: La méthode de chaînage (comme Foo.DoX().DoY().DoZ()) est agréable, mais ce n'est certainement pas la seule façon de faire quelque chose. Composition de fonction (comme doZ . doY . doX $ fooest une alternative parfaitement valable.
Anon.
1
@Joris: une question sur laquelle je m'interroge depuis longtemps (moi-même bioinformaticien): si la performance compte autant, pourquoi utiliser Perl en premier lieu au lieu de C ++? Si vous craignez de réduire d'un facteur 10 le temps d'exécution (préoccupation valable!), Le passage au C ++ vous procure une gratification immédiate. Bien sûr, le langage est nul… mais ensuite Perl aussi… et il existe de bonnes bibliothèques de bioinformatique pour C ++.
Konrad Rudolph
1
@ Konrad: Cela dépend. BioPerl a sans doute le plus de packages pour les bioinformaticiens de toutes les langues (je pense que Python est en train de rattraper son retard). De plus, beaucoup de travail a été fait dans Perl et adapter un script est plus facile que de tout réécrire en C ++. Enfin, il ne sert pas à écrire une application complète quand un script fera. Je suppose que c'est la raison pour laquelle Perl est toujours aussi présent. Et honnêtement, ça ne me dérange pas, j'aime la langue. C'est toujours le meilleur que je connaisse pour le travail des chaînes et des fichiers. Les calculs sont évidemment effectués dans d'autres langues et liés (ce qui est assez facile).
Joris Meys
1
@ Konrad: cela dépend de la façon dont on le fait. Il est possible de tout faire en Perl, mais Perl peut être facilement lié à d'autres outils, notamment sous Linux. J'utilise souvent Perl en tant que script bash avancé avec une forte manipulation des chaînes et une construction facile des jeux de données à déposer dans d'autres applications.
Joris Meys
27

Ayant passé plusieurs années dans les formulaires Web ASP.NET, je devrais dire sans équivoque:

L'interface utilisateur intelligente

Bien qu'il soit tout à fait possible de créer des applications multicouches et testables dans des formulaires Web, Visual Studio facilite trop la tâche des développeurs pour leur permettre de cliquer en un clic sur des formulaires étroitement liés à leur source de données, la logique de l'application étant jalonnée de tout le code de l'interface utilisateur.

Steve Sanderson explique cet anti-motif beaucoup mieux que je ne le pouvais dans son livre Pro ASP.NET MVC:

Pour créer une application Smart UI, un développeur construit d'abord une interface utilisateur, généralement en faisant glisser une série de widgets d'interface utilisateur sur un canevas, puis il remplit le code du gestionnaire d'événements pour chaque clic de bouton possible ou tout autre événement d'interface utilisateur. Toute la logique de l'application réside dans ces gestionnaires d'événements: logique permettant d'accepter et de valider les entrées de l'utilisateur, d'effectuer l'accès et le stockage des données et de fournir des informations en mettant à jour l'interface utilisateur. L'ensemble de l'application est constitué de ces gestionnaires d'événements. C'est ce qui a tendance à apparaître par défaut lorsque vous placez un novice devant Visual Studio. Dans cette conception, il n'y a aucune séparation des préoccupations. Tout est fusionné, organisé uniquement en fonction des différents événements de l'interface utilisateur pouvant se produire. Lorsque des règles logiques ou métier doivent être appliquées dans plusieurs gestionnaires, le code est généralement copié et collé. ou certains segments choisis aléatoirement sont factorisés dans des classes d’utilitaires statiques. Pour de nombreuses raisons évidentes, ce type de motif est souvent appelé anti-motif.

richeym
la source
1
Une interface graphique est au moins une sorte de code de spécification à respecter. Je ne pense pas que les programmeurs qu'il décrit feraient mieux si on leur présentait plutôt un fichier texte vierge.
4
@ QPR, je ne sais pas à ce sujet. S'ils avaient un fichier texte vierge, ils ne pourraient peut-être rien faire (ce qui pourrait n'être qu'un bonus).
Ken Henderson
L’un des nombreux avantages de l’utilisation de WPF est que l’implémentation de MVVM réduit cet anti-motif en un rien de temps.
Robert Rossney le
2
Mille fois ça. Je vois même des développeurs .NET expérimentés s'appuyer sur ce "modèle" car il est plus facile que de comprendre ou de se soucier de la séparation des problèmes. Même s'ils n'utilisent pas les assistants glisser-déposer, le "modèle" le plus courant dans le développement .NET WebForms consiste à tout faire dans des événements code-behind et à copier / coller du code selon les besoins.
Wayne Molina
23

Je le vois de temps en temps et cela résulte généralement d'une compréhension insuffisante des expressions booléennes.

if (someCondition == true)
Corey
la source
16
Cela a l'avantage de rendre le code plus explicite
Pemdas
7
Je pense qu’il faut jeter un coup d’œil à cette question: programmers.stackexchange.com/questions/12807/…
gablin
5
Je ne fais pas ça, mais sérieusement, surmontez-vous. Il y a bien pire. :)
MetalMikester
4
Si vous avez correctement nommé vos variables, par exemple en boolcommençant par isou has, vous n’avez pas besoin de rendre votre code plus explicite = true.
Personne le
3
@DisgruntledGoat, car il ne devrait pas être utilisé du tout
Corey
19

Réimplémentation de la fonctionnalité de base (ou fournie d'une autre manière), soit en raison de son ignorance de son existence, soit en raison d'un besoin perçu de personnalisation.

l0b0
la source
2
L'apprentissage est une exception. Quand on étudie quelque chose, il est souvent bénéfique de "réinventer la roue".
Maxpm
Bien sûr, j'aurais dû préciser que c'est pertinent uniquement lors de la création d'un logiciel de production.
l0b0
1
Ceci est particulièrement grave lors de la mise en œuvre de tout ce qui concerne la sécurité. Un bon logiciel de sécurité empêche les attaques auxquelles la plupart des gens ne pensent même jamais.
David Thornley
Je vois ce chemin trop commun. Nous avons besoin de X, écrivons le nôtre! Mais qu'en est-il du paquet open-source Y? Non, nous avons besoin de logiciels personnalisés pour nos secrets commerciaux super secrets qui sont les mêmes que tous les autres de notre secteur. Nous ne pouvons pas utiliser de logiciel de traitement des ordures commun!
Wayne Molina
18

Héritage.

Ne pas imposer, c’est là où cela n’a aucun sens.

Trousse
la source
6
Le problème est qu'intuitivement, «is-a» apparaît très souvent logique (en particulier, chaque relation de mise en œuvre / contrat pouvant être exprimée de manière familière par «is-a»). Il faut une solide compréhension de la programmation orientée objet pour se rendre compte que c'est en fait une erreur et que la mise en œuvre de l'héritage et de l'interface est fondamentalement différente.
Konrad Rudolph
@ Konrad - d'accord absolument. J'essaie d'encourager les gens à commencer avec la composition , à passer aux interfaces et à envisager l'héritage en dernier. (En règle générale, bien sûr). Mais peut-être que c'est mon histoire de VB qui parle ... ;-)
Mike Woodhouse Le
1
Ceci est en grande partie une question de conception linguistique, cependant. La raison pour laquelle vous devriez "préférer la composition à l'héritage (d'implémentation)" dans des langages tels que Java ou C #, est parce que l'héritage d'implémentation est nul dans ces langages. Certaines personnes critiquent la construction de logiciels orientés objet de Bertrand Meyer pour une utilisation excessive de l'héritage, mais quand vous regardez réellement Eiffel (le langage utilisé dans le livre), vous réalisez qu'il a été conçu pour l'implémentation de l'héritage , et qu'il est donc correct d'utiliser l'héritage composition. Dans ce cas, au moins.
Jörg W Mittag le
14

Personnalisation des logiciels disponibles dans le commerce.

Bien que je sache que cela peut être utile, je me demande combien d’argent est dépensé pour faire de petites choses pour des gains discutables. C’est là qu’une entreprise peut dépenser des centaines, voire des millions de dollars, en licences de certains logiciels, qui sont ensuite personnalisés, car ils sont tellement configurables, modifiables et flexibles qu’ils ne font pas grand-chose par défaut. En fin de compte, il s’agit d’une application personnalisée à cause du nouveau code ajouté à ce qui a été acheté.

JB King
la source
N'est-ce pas plus susceptible d'être le cas avec une application personnalisée?
JeffO
13

Utiliser le compliant comme un débogueur.

Ignorer les avertissements de conformité ou les désactiver complètement.

Variables globales.

Pemdas
la source
18
Qu'est-ce qui ne va pas avec "l'utilisation du compilateur en tant que débogueur"? Avoir un compilateur capable de signaler les erreurs dans votre code avant qu'elles ne deviennent un problème au moment de l'exécution constitue un avantage considérable.
Mason Wheeler
3
Je compte sur le compilateur pour détecter les erreurs de syntaxe et les erreurs de correspondance de type incorrectes. Pour les erreurs de comportement, je me base sur des cas de test.
Gablin
5
Le problème vient du moment où vous commencez à vous fier au compilateur pour assurer la correction du programme. Est-ce que cela a été compilé? Non, laissez-moi vous parler de cette petite section et voir si cela résout le problème. At-il compilé? Non, laissez-moi ajouter un * ici et là et voir si compile. ... ect. Évidemment, c'est utile pour corriger les fautes de frappe
Pemdas
2
Vous dites que c'est comme si le codeur cherchait aveuglément à essayer de faire quelque chose - n'importe quoi - pour que le code soit compilé d'une manière ou d'une autre. Ce n'est pas comme ça que ça marche IME; le compilateur vous envoie un message d'erreur utile et vous indique l'emplacement de l'erreur. Généralement, si quelque chose ne compile pas, vous avez écrit vous-même le nouveau code. Vous avez donc une bonne idée de ce qui ne va pas et de la façon de le réparer une fois qu'il est pointé. en dehors. (Bien que si vous lancez des * aléatoires, vous travaillerez peut-être en C ++, où les erreurs du compilateur sont réputées être extrêmement inutiles, alors ce que j'ai dit peut ne pas s'appliquer.)
Mason Wheeler
3
Compter sur le compilateur fonctionne très bien, étant donné un système de type assez fort et une base de code bien typée. Souvent, le système de types peut modéliser des contraintes importantes pour lesquelles vous auriez sinon à écrire des tests (par exemple, dans des systèmes faiblement typés). Donc , judicieusement utilisé, le compilateur (et en particulier son type checker) est un grand atout pour tests et le débogage, et il n'y a rien de mal à compter sur elle. En particulier, il est faux de dire qu'un compilateur ne peut afficher que des erreurs de syntaxe.
Konrad Rudolph
11

Tous les modèles de conception.

Ils sont comme le sel ou le sucre. Certains d’entre eux rendent votre nourriture géniale, beaucoup d’entre eux rendent votre nourriture nulle.

Ne vous méprenez pas. Les modèles de conception sont des techniques merveilleuses. Je les ai beaucoup utilisés. Mais parfois, je trouve des programmeurs (dont certains sont mes ex-patrons), qui avaient ces "vous devez utiliser un motif de conception", même si cela ne correspond pas au problème !!!

Un exemple est le "modèle de visiteur" qui est plus destiné aux "collections linéaires / séquentielles". J'ai dû travailler une fois avec une structure de données arborescente. Afin de "visiter" chaque élément, je code une méthode de modèle non-design, et un ancien patron insiste pour utiliser ou adapter le "modèle de visiteur". Ensuite, je navigue sur le net, pour un deuxième avis. Eh bien, d'autres programmeurs avaient la même situation et la même solution. Et appelez-le "Modèle de visiteur arbre / hiérarchique"., Comme un nouveau modèle de conception

J'espère que c'est ajouté en tant que nouveau modèle aux modèles existants, dans une nouvelle version du livre "Design Patterns".

umlcat
la source
3
Je n'utilise jamais de modèles de conception, même s'ils apparaissent parfois naturellement dans mon code.
configurateur
Comment va le dicton? Vous commencez à utiliser des motifs sans savoir que vous les utilisez, vous les apprenez et les utilisez partout, puis ils deviennent une seconde nature et vous commencez à les utiliser sans savoir que vous les utilisez?
Wayne Molina
2
@configurator Quand je lis sur les modèles de conception; Je découvre également que moi-même et d’autres développeurs
utilisions
9

Utiliser des exceptions comme contrôle de flux. Sorte de semblable à cette réponse , mais différent.

Avaler des exceptions est une mauvaise forme car cela introduit des bogues mystérieux et difficiles à trouver dans le code. En revanche, utiliser des exceptions comme contrôle de flux est une mauvaise solution car il rend le code beaucoup plus inefficace qu’il pourrait l’être et est conceptuellement bâclé.

La gestion des exceptions ne doit être utilisée que pour gérer des scénarios vraiment exceptionnels (duh), imprévus, et non des choses comme un utilisateur tapant un caractère alphabétique où un nombre est attendu. Ce type d'abus d'exception est extrêmement courant chez les mauvais programmeurs du monde Java.

3 tours
la source
Les exceptions générant du code inefficace dépendent de votre langue - création d'un cadre de pile, etc. etc. Dans Squeak, votre pile est complètement réifiée, il n'y a donc aucune différence entre utiliser des exceptions et ne pas en utiliser. (En d'autres termes, les exceptions font partie de la bibliothèque, pas le langage.) Toutefois, il est compliqué de travailler avec un flux de contrôle contrôlé par des exceptions: lshift.net/blog/2011/01/04/try-again-with-exceptions montre une boucle utilisant des exceptions que j'ai récemment trouvée.
Frank Shearar
En ce qui concerne le dernier paragraphe, cela dépend de votre langue. Les exceptions ("conditions") dans Common Lisp sont un sur-ensemble strict des idées d'exceptions de la plupart des langages. Voir des exemples ici: gigamonkeys.com/book/… Comme pour tout, vous pouvez aller trop loin!
Frank Shearar le
La lisibilité et la maintenabilité l'emportent sur les performances. Les cas où j'utiliserai des exceptions pour réussir (ce que je suppose que vous entendez par «contrôle de flux») sont très rares, mais ils peuvent donner un code plus propre, par exemple une recherche récursive complexe. De manière générale, je suis d'accord cependant. Par exemple, j'ai des conteneurs avec des méthodes itérateur qui retournent false pour sortir de la plage (commune à la fin d'une itération), mais émettent une exception si l'itérateur est "null" (signe probable d'une incohérence interne)
Steve314
7

Je vais aller avec inflexibilité par la dissimulation excessive de données.

Nous savons tous que l'abstraction et la dissimulation de la mise en œuvre sont bonnes, mais plus n'est pas toujours meilleur. Si vous en faites trop, vous pouvez obtenir un résultat inflexible qui ne peut pas faire face aux changements d’exigences. Pour gérer le changement, vous devez non seulement modifier la classe qui doit gérer ce changement, mais vous devez également créer un moyen pour que les informations dont il n'a jamais eu besoin auparavant soient accessibles malgré les couches de données masquées.

Le problème est que, comme pour tout problème de trouver le bon équilibre pour chaque contexte, il faut de l'expérience.

Steve314
la source
6

Etat mutable et boucles. Vous n’avez presque jamais besoin d’eux, et vous obtenez presque toujours un meilleur code sans eux.

Par exemple, cela provient directement d'un thread StackOverflow:

// ECMAScript
var thing, things_by_type = {};
for (var i = 0; i < things.length; i++) {
    thing = things[i];
    if(things_by_type[thing.type]) {
        things_by_type[thing.type].push(thing);
    } else {
        things_by_type[thing.type] = [thing];
    }
}

# Ruby
things_by_type = {}
things.each do |thing|
  (things_by_type[thing.type] ||= []) << thing
end

Ils font tous les deux la même chose. Mais je n'ai aucune idée de ce qu'ils font. Heureusement, la question explique en fait ce qu’ils font, alors j’ai pu les réécrire comme suit:

// ECMAScript
things.reduce(function (acc, thing) {
    (acc[thing.type] || (acc[thing.type] = [])).push(thing);
    return acc;
}, {});

# Ruby
things.group_by(&:type)

// Scala
things groupBy(_.type)

// C#
from thing in things group thing by thing.Type // or
things.GroupBy(thing => thing.Type);

Il n'y a pas de boucles et pas d'état mutable. Bon, d'accord, pas de boucles explicites ni de compteurs de boucles.

Le code est devenu beaucoup plus court, beaucoup plus simple, et ressemble beaucoup plus à une description de ce qu’il est censé faire (en particulier dans l’affaire Ruby, il est dit directement "grouper les choses par type"), et beaucoup moins sujet aux erreurs. Il n'y a pas de risque de fuite à la fin du tableau, d'erreurs poteau clôturé ou d'erreurs décalées avec les indices de boucle et les conditions de terminaison, car il n'y a pas d' indices de boucle et de conditions de terminaison.

Jörg W Mittag
la source
Je crois que dans la deuxième ligne de votre "corrigé" ECMAScript devrait lire (acc[thing.type] || (acc[thing.type] = [])), par opposition à "= [chose] , unless you want to add " à la liste deux fois ... Ou est-ce que quelque chose me manque?
Austin Hyde
@ Austin Hyde: Vous avez raison.
Jörg W Mittag le
1
Cet exemple ecmascript est incompréhensible pour beaucoup de programmeurs. Il repose sur trop d’astuces syntaxiques. La boucle a l’avantage d’évidence pour les développeurs débutants.
Joeri Sebrechts
6

Railleur. Cela introduit trop d'exigences artificielles pour un découplage excessif dans votre code, conduit à un code de raviolis trop sophistiqué et oblige une conception de style OO dans votre gorge alors qu'une conception plus procédurale ou fonctionnelle pourrait être une solution plus simple à votre problème.

Dsimcha
la source
D'accord en théorie; se moque sont utiles mais vous n'avez de les avoir.
Wayne Molina
Le caractère invasif de la moquerie dépend de la langue que vous utilisez. En C #, cela peut être très invasif et ajoute des interfaces inutilisées.
Frank Hileman
3

Les programmeurs Delphi du monde entier ont découvert au cours des deux dernières années à quel point il est difficile d’utiliser des tableaux de caractères pour stocker des octets en raison de la conversion Unicode totale

Et, "bientôt", nous verrons combien il est difficile de stocker des entiers dans des listes lorsque nous souhaitons passer à la version 64 bits.

Peter Turner
la source
2
Je pense qu'une grande partie des problèmes Unicode n'aurait jamais été soulevée si Borland avait déclaré un type DataString qui était fondamentalement identique à AnsiString, mais spécifiquement destiné à être utilisé avec des blobs, et dont les utilisateurs étaient au courant.
Mason Wheeler
2

Propriétés. Je sais que cela suscite la controverse, mais j’estime que les propriétés sont beaucoup trop utilisées dans .net.

Quelle est la différence entre ces deux lignes?

public string Property { get; set; }

public string Field;

Pour le développeur, la différence est la suivante: absolument rien. La forme compilée est un petit différent peu, donc si vous écrivez une bibliothèque, et que la bibliothèque va être mis à jour dans les programmes, et vous ne pouvez pas recompiler les programmes eux - mêmes (par exemple , si vous écrivez une interface pour plug - ins devrait fonctionner avec toutes les versions de votre logiciel), vous ne devriez pas utiliser de champs publics, car vous ne pouvez pas les remplacer par des propriétés. Dans les autres cas, il n'y a absolument aucune différence entre utiliser un champ ou une propriété automatique sans modificateurs.

configurateur
la source
1
D'accord; si vous savez à 100% que vous n'aurez jamais rien à faire pour obtenir / définir une "propriété", il n'y a aucune raison de posséder une propriété. Cependant, s'il y a une chance que vous deviez faire quelque chose (en notant qu'une valeur a été modifiée, par exemple), vous devez utiliser une propriété. Personnellement , je ne vois pas une différence assez grande pour ne pas utiliser la propriété, juste au cas où vous avez besoin de le modifier plus tard (je sais, je sais , YAGNImais je me sens déviant dans ce cas , ne rien coût)
Wayne Molina
2
@Wayne: Comment évolue-t-on ;vers { get { ... } set { ... } }plus de travail que { get; set; }vers { get { ... } set { ... } }?
configurateur
Maintenant que j'y pense, c'est un bon argument.
Wayne Molina