J'ai assisté à un événement de fabrication de logiciels il y a quelques semaines et l'un des commentaires a été: "Je suis sûr que nous reconnaissons tous le mauvais code quand nous le voyons" et tout le monde a hoché la tête sans plus de discussion.
Ce genre de chose m'inquiète toujours car il y a ce truisme que tout le monde pense être un conducteur supérieur à la moyenne. Bien que je pense que je peux reconnaître un mauvais code, j'aimerais en savoir plus sur ce que les autres considèrent comme le code sent car il est rarement discuté en détail sur les blogs des gens et seulement dans une poignée de livres. En particulier, je pense qu'il serait intéressant d'entendre parler de tout ce qui est une odeur de code dans une langue mais pas dans une autre.
Je vais commencer par un simple:
Code dans le contrôle de code source qui a une proportion élevée de code commenté - pourquoi est-il là? était-il censé être supprimé? est-ce un travail à moitié fini? Peut-être que cela n'aurait pas dû être commenté et n'a été fait que lorsque quelqu'un testait quelque chose? Personnellement, je trouve ce genre de chose vraiment ennuyeux même si ce n'est que la ligne bizarre ici et là, mais quand vous voyez de gros blocs entrecoupés du reste du code, c'est totalement inacceptable. C'est aussi généralement une indication que le reste du code est également susceptible d'être de qualité douteuse.
/* Fuck this error */
Généralement trouvé dans un non-sens try..catch
bloc, il a tendance à attirer mon attention. À peu près aussi bien que /* Not sure what this does, but removing it breaks the build */
.
Encore quelques choses:
if
process
, data
, change
, rework
, modify
Celui que je viens de trouver:
/* Stupid database */
$conn = null;
while(!$conn) {
$conn = mysql_connect("localhost", "root", "[pass removed]");
}
/* Finally! */
echo("Connected successfully.");
C'est vrai, parce qu'avoir à forcer vos connexions MySQL est la bonne façon de faire les choses. Il s'avère que la base de données rencontrait des problèmes avec le nombre de connexions, ils ont donc continué à expirer. Au lieu de déboguer cela, ils ont simplement essayé encore et encore jusqu'à ce que cela fonctionne.
Le drapeau rouge majeur pour moi est les blocs de code dupliqués, car cela montre que la personne ne comprend pas les principes fondamentaux de la programmation ou avait trop peur de faire les changements appropriés à une base de code existante.
J'avais l'habitude de compter le manque de commentaires comme un drapeau rouge, mais ayant récemment travaillé sur beaucoup de très bon code sans aucun commentaire, je suis revenu sur cela.
Code qui essaie de montrer à quel point le programmeur est intelligent, malgré le fait qu'il n'ajoute aucune valeur réelle:
x ^= y ^= x ^= y;
20 000 fonctions de ligne (exagérées). Toute fonction nécessitant plus de deux écrans doit être refacturée.
Dans le même ordre d'idées, les fichiers de classe qui semblent durer éternellement. Il y a probablement quelques concepts qui pourraient être résumés en classes qui clarifieraient le but et la fonction de la classe d'origine, et probablement où elle est utilisée, à moins que ce ne soient toutes des méthodes internes.
variables non descriptives, non triviales ou trop de variables triviales non descriptives. Cela fait de la déduction de ce qui se passe réellement une énigme.
{ Let it Leak, people have good enough computers to cope these days }
Le pire, c'est que ça vient d'une bibliothèque commerciale!
Les commentaires sont si verbeux que s'il y avait un compilateur anglais, il se compilerait et s'exécuterait parfaitement, mais ne décrit rien de ce que le code ne fait pas.
//Copy the value of y to temp.
temp = y;
//Copy the value of x to y.
y = x;
//Copy the value of temp to x.
x = temp;
En outre, les commentaires sur le code qui auraient pu être supprimés si le code avait respecté certaines directives de base:
//Set the age of the user to 13.
a = 13;
Code qui génère des avertissements lors de la compilation.
Fonctionne avec des nombres dans le nom au lieu d'avoir des noms descriptifs, comme:
void doSomething()
{
}
void doSomething2()
{
}
S'il vous plaît, faites en sorte que les noms de fonction signifient quelque chose! Si doSomething et doSomething2 font des choses similaires, utilisez des noms de fonction qui différencient les différences. Si doSomething2 est une sortie de fonctionnalité de doSomething, nommez-le pour sa fonctionnalité.
Magic Numbers ou Magic Strings.
if (accountBalance>200) { sendInvoice(...); }
salesPrice *= 0.9; //apply discount
if (invoiceStatus=="Overdue") { reportToCreditAgency(); }
Peut-être pas le pire mais montre clairement le niveau des implémenteurs:
if(something == true)
Si une langue a une boucle for ou une construction d'itérateur, l'utilisation d'une boucle while montre également le niveau de compréhension du langage par les implémenteurs:
count = 0;
while(count < items.size()){
do stuff
count ++;
}
for(i = 0; i < items.size(); i++){
do stuff
}
//Sure this is not terrible but use the language the way it was meant to be used.
Mauvaise orthographe/grammaire dans la documentation/commentaires mange presque autant que le code lui-même. La raison en est que le code était destiné aux humains à lire et aux machines à fonctionner. C'est pourquoi nous utilisons des langages de haut niveau, si votre documentation est difficile à traverser, cela me fait de manière préventive une opinion négative de la base de code sans la regarder.
Celui que je remarque immédiatement est la fréquence de blocs de code profondément imbriqués (si, tout, etc.). Si le code est fréquent pour plus de deux ou trois niveaux de profondeur, c'est le signe d'un problème de conception/logique. Et si elle va comme 8 nids de profondeur, il vaut mieux avoir une sacrée bonne raison pour qu'elle ne soit pas brisée.
Lorsque je note le programme d'un élève, je peux parfois le dire en un clin d'œil. Ce sont les indices instantanés:
Rarement mes premières impressions sont incorrectes, et ces avertissements ont raison à propos de 95% du temps. À une exception près, un étudiant nouveau dans la langue utilisait un style d'un langage de programmation différent. En creusant et en relisant leur style dans l'idiome de l'autre langue, j'ai sonné l'alarme, et l'élève a ensuite obtenu le plein crédit. Mais de telles exceptions sont rares.
Lorsque je considère un code plus avancé, voici mes autres avertissements:
En termes de style, je n'aime généralement pas voir:
Ce sont seulement des indices au mauvais code. Parfois, ce qui peut sembler être du mauvais code ne l'est vraiment pas, car vous ne connaissez pas les intentions du programmeur. Par exemple, il peut y avoir une bonne raison pour laquelle quelque chose semble trop complexe - il peut y avoir eu une autre considération en jeu.
Préféré personnel/animal de compagnie: IDE noms générés qui sont validés. Si TextBox1 est une variable majeure et importante dans votre système, vous avez une autre chose à venir lors de la révision du code.
Variables complètement inutilisées, en particulier lorsque la variable a un nom similaire aux noms de variables utilisés.
Beaucoup de gens ont mentionné:
//TODO: [something not implemented]
Bien que je souhaite que ces choses soient mises en œuvre, au moins ils ont fait une note. Ce que je pense est pire:
//TODO: [something that is already implemented]
Les Todo sont sans valeur et déroutants si vous ne vous embêtez jamais à les supprimer!
Conjonctions dans les noms de méthode:
public void addEmployeeAndUpdatePayrate(...)
public int getSalaryOrHourlyPay(int Employee) ....
Clarification: La raison pour laquelle cela sonne l'alarme est qu'il indique que la méthode viole probablement le principe de responsabilité unique .
Une méthode qui m'oblige à faire défiler vers le bas pour tout lire.
Lier évidemment le code source de la GPL à un programme commercial à source fermée.
Non seulement cela crée un problème juridique immédiat, mais d'après mon expérience, cela indique généralement une négligence ou une insouciance qui se reflète également ailleurs dans le code.
Indépendant de la langue:
TODO: not implemented
int function(...) { return -1; }
(identique à "non implémenté")0
, -1
Ou null
comme valeurs de retour exceptionnelles.Spécifique au langage (C++):
array new
Qui n'est apparemment pas sûr pour RAII.printf
.spécifique à Microsoft C++:
spécifique C++/OOP:
Utiliser beaucoup de blocs de texte plutôt que des énumérations ou des variables définies globalement.
Pas bon:
if (itemType == "Student") { ... }
Meilleur:
private enum itemTypeEnum {
Student,
Teacher
}
if (itemType == itemTypeEnum.Student.ToString()) { ... }
Meilleur:
private itemTypeEnum itemType;
...
if (itemType == itemTypeEnum.Student) { ... }
Style d'indentation bizarre.
Il y a quelques styles très populaires, et les gens porteront ce débat à la tombe. Mais parfois, je vois quelqu'un utiliser un style d'indentation vraiment rare, ou même maison. C'est un signe qu'ils n'ont probablement pas codé avec quelqu'un d'autre qu'eux-mêmes.
Paramètres mal typés ou valeurs de retour sur les méthodes.
public DataTable GetEmployees() {...}
public DateTime getHireDate(DataTable EmployeeInfo) {...}
public void FireEmployee(Object EmployeeObjectOrEmployeeID) {...}
Odeur de code: ne suit pas les meilleures pratiques
Ce genre de chose m'inquiète toujours car il y a ce truisme que tout le monde pense être un conducteur supérieur à la moyenne.
Voici un flash d'information pour vous: 50% de la population mondiale est inférieure à la moyenne du renseignement. Ok, donc certaines personnes auraient une intelligence exactement moyenne, mais ne soyons pas difficiles. De plus, l'un des effets secondaires de la stupidité est que vous ne pouvez pas reconnaître votre propre stupidité! Les choses ne semblent pas si bonnes si vous combinez ces déclarations.
Quelles choses sonnent instantanément l'alarme lorsque vous regardez le code?
Beaucoup de bonnes choses ont été mentionnées, et en général, il semble que ne suit pas les meilleures pratiques est une odeur de code.
Les meilleures pratiques ne sont généralement pas inventées au hasard et sont souvent là pour une raison. Souvent, cela peut être subjectif, mais d'après mon expérience, ils sont généralement justifiés. Suivre les meilleures pratiques ne devrait pas être un problème, et si vous vous demandez pourquoi elles sont telles qu'elles sont, recherchez-les plutôt que de les ignorer et/ou de vous en plaindre - peut-être que c'est justifié, peut-être pas.
Un exemple de meilleure pratique pourrait être d'utiliser des curlies avec chaque bloc if, même s'il ne contient qu'une seule ligne:
if (something) {
// whatever
}
Vous ne pensez peut-être pas que c'est nécessaire, mais j'ai récemment l que c'est une source majeure de bugs. Toujours utiliser des crochets a également été discuté sur Stack Overflow , et vérifier que les instructions if ont des crochets est également un règle in PMD , un analyseur de code statique pour Java.
Rappelez-vous: "Parce que c'est la meilleure pratique" n'est jamais une réponse acceptable à la question "pourquoi faites-vous cela?" Si vous ne pouvez pas expliquer pourquoi quelque chose est une meilleure pratique, alors ce n'est pas une meilleure pratique, c'est une superstition.
if...else
, Il devient un bloc if...else if...[...]...else
$lesseeloginaccountservice
if
trop compliquées. Exemple de code: if (!($lessee_obj instanceof Lessee && $lessee_obj != NULL))
que j'ai chompé en if ($lessee_obj == null)
Attraper les exceptions générales:
try {
...
} catch {
}
ou
try {
...
} catch (Exception ex) {
}
Surutilisation de la région
Typiquement, utiliser trop de régions m'indique que vos classes sont trop grandes. C'est un indicateur d'avertissement qui signale que je devrais enquêter davantage sur ce morceau de code.
Quelqu'un peut-il penser à un exemple où le code devrait se référer légitimement à un fichier par chemin absolu?
Des commentaires qui disent "c'est parce que la conception du sous-système froz est totalement falsifiée".
Cela continue sur un paragraphe entier.
Ils expliquent que la refonte suivante doit se produire.
Mais ne l'a pas fait.
Maintenant, on aurait pu leur dire qu'ils ne pouvaient pas le changer par leur patron à l'époque, à cause de problèmes de temps ou de compétence, mais c'était peut-être à cause des gens mesquins.
Si un superviseur pense que c'est aléatoire. le programmeur ne peut pas effectuer une refactorisation, alors le superviseur devrait le faire.
Quoi qu'il en soit, je sais que le code a été écrit par une équipe divisée, avec une politique de pouvoir possible, et ils n'ont pas refactorisé les conceptions de sous-systèmes borked.
Histoire vraie. Ça pourrait t'arriver.
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
Bien sûr, sans aucune sorte de documentation et les _ #define
s
Code C++ avec des instructions de suppression explicites (sauf si je regarde les entrailles d'une implémentation de pointeur intelligent). 'delete' est le 'goto' de la gestion de la mémoire IMHO .
Étroitement lié à cela, un code comme:
// Caller must take ownership
Thing* Foo::Bar()
(Et comptez-vous chanceux s'il y a le commentaire!). Ce n'est pas comme si les pointeurs intelligents étaient des fusées. std::auto_ptr
est fait pour ce genre de chose (documenter et appliquer l'intention exprimée dans le commentaire) et fait partie de la standard = depuis des lustres maintenant.
Ensemble, ils crient du code hérité mal aimé, ou des responsables avec un état d'esprit coincé quelque part au début des années 90.
Fonctions qui réimplémentent les fonctionnalités de base du langage. Par exemple, si vous voyez une méthode "getStringLength ()" en JavaScript au lieu d'un appel à la propriété ".length" d'une chaîne, vous savez que vous êtes en difficulté.
Conventions de dénomination des classes qui démontrent une mauvaise compréhension de l'abstraction qu'elles tentent de créer. Ou qui ne définissent pas du tout une abstraction.
Un exemple extrême me vient à l'esprit dans une classe VB que j'ai vue une fois et qui était intitulée Data
et comptait plus de 30 000 lignes ... dans la première C'était une classe partielle divisée en au moins une demi-douzaine d'autres fichiers. La plupart des méthodes étaient des wrappers autour de procs stockés avec des noms comme FindXByYWithZ()
.
Même avec des exemples moins dramatiques, je suis sûr que nous venons tous de "déverser" la logique dans une classe mal conçue, en lui donnant un titre entièrement générique, et en le regrettant plus tard.
ON ERROR RESUME NEXT
Devoir maintenir Classic ASP applications est malheureusement une nécessité pour la plupart des développeurs ASP.NET, mais ouvrir un fichier include commun et voir que sur la première ligne est destructeur d'âme.
Lorsqu'il n'y a aucun commentaire ou documentation sur ce que le code fait ou est censé faire (c'est-à-dire "le code est la documentation").
Méthodes ou variables avec un nombre comme suffixe (par exemple Login2 ()).
try { //do something } catch{}
Code qui ne peut jamais, entrez logiquement le chemin d'exécution.
var product = repository.FindProduct(id);
log.Info("Found product " + product.Name);
if (product != null)
{
// This will always happen
}
else
{
// **This won't ever happen**
}
ou
if (messages.Count > 0)
{
// Do stuff with messages
}
else if (messages.Count == 1)
{
// **I hope this code isn't important...**
}
De mon point de vue centré sur Java:
final
manquant dans les champs.catch
blocs sans code utile (mauvais: commentaires, printf, journalisation ou simplement vide).Utiliser un objet caché dans l'interface utilisateur (par exemple, une zone de texte) pour stocker une valeur plutôt que de définir une variable correctement délimitée et typée.
Chaque fois que je lis ce qui suit:
//Don't put in negative numbers or it will crash the program.
Ou quelque chose de similaire. Si tel est le cas, inscrivez-vous! Laissez le débogueur savoir que pendant l'exécution, vous ne voulez pas ces valeurs et assurez-vous que le code énonce le contrat avec l'appelant.
Ce type de code:
if (pflayerdef.DefinitionExpression == "NM_FIELD = ' '" || One.Two.nmEA == "" ||
One.Two.nmEA == " " || One.Two.nmEA == null ||
One.Two.nmEA == " ")
{
MessageBox.Show("BAD CODE");
return;
}
Il s'agit d'une véritable base de code de production en direct!
Quant aux nombres magiques: ils sont mauvais s'ils sont utilisés à différents endroits et le changer nécessite de le synchroniser à plusieurs endroits. Mais un nombre en un seul endroit n'est pas pire que d'avoir une constante pour désigner un nombre qui est toujours utilisé en un seul endroit.
De plus, les constantes peuvent ne pas avoir beaucoup de place dans votre application. Dans de nombreuses applications de base de données, ces éléments doivent être stockés dans la base de données selon l'application ou les paramètres utilisateur. Et pour terminer leur mise en œuvre, ils impliquent ce paramètre et une place dans l'interface utilisateur et une note dans la documentation de l'utilisateur final ... tout cela est une sorte de sur-ingénierie et un gaspillage de ressources si tout le monde est parfaitement satisfait lorsque le nombre est 5 ( et 5 c'est.)
Je pense que vous pouvez laisser des nombres et des chaînes en place jusqu'à ce qu'il soit nécessaire d'utiliser ce numéro en dehors de cet endroit. Ensuite, il est temps de refaçonner les choses vers une conception plus flexible.
En ce qui concerne les chaînes ... Je connais les arguments, mais c'est un endroit de plus, il est inutile de faire une conversion d'une chaîne à une constante. Surtout si les chaînes en place proviennent de toute façon d'une implémentation constante (par exemple, les importations qui sont générées à partir d'une application externe et qui ont une chaîne d'état courte et reconnaissable, tout comme 'En retard'). beaucoup de point dans la conversion du "retard" en STATUS_OVERDUE quand il est utilisé dans un seul endroit de toute façon.
Je suis très pour ne pas ajouter de complexité si elle ne crée pas réellement les avantages nécessaires sur la flexibilité, la réutilisation ou la vérification des erreurs. Lorsque vous avez besoin de flexibilité, codez-le correctement (le truc de refactor). Mais si ce n'est pas nécessaire ...
Code étroitement couplé. Surtout quand vous voyez beaucoup de choses codées en dur (noms d'imprimantes réseau, adresses IP, etc.) au milieu du code. Ceux-ci devraient être dans un fichier de configuration ou même des constantes, mais ce qui suit ne fera que causer des problèmes:
if (Host_ip == '192.168.1.5'){
printer = '192.168.1.123';
} else
printer = 'prntrBob';
Un jour, Bob va quitter et son imprimante sera renommée. Un jour, l'imprimante obtiendra une nouvelle adresse IP. Un jour, 192.168.1.5 voudra imprimer sur l'imprimante de Bob.
mon mantra préféré: écrivez toujours du code comme un psychopathe homicide qui sait où vous vivez devra le maintenir!
Code qui montre que le programmeur ne s'est jamais adapté, il y a des années, à Java 5:
Ne connaissant pas les méthodes modernes multithread.
Pour SQL:
Le premier grand indicateur est l'utilisation de jointures implicites.
Ensuite, l'utilisation d'une jointure gauche sur tableB combinée à une clause WHERE comme:
WHERE TableB.myField = 'test'
Si vous ne savez pas que cela donnera des résultats incorrects, je ne peux pas croire que toute requête que vous écrivez donnera des résultats corrects.
Notre code VB6 hérité, vous pouvez ouvrir n'importe quelle page de code de module ou de formulaire et trouver un écran plein de Public ou Global # & @ ! Variables déclarées en haut, référencées de partout dans le @ &!! (*! # programme. ARGH !!!!
(Ouf, je devais retirer ça :-))
Quelque chose comme ça
x.y.z.a[b].c
Cela sent le bio-risque. Cette référence à de nombreux membres n'est jamais un bon signe. Et oui, c'est une expression typique dans le code avec lequel je travaille.
quelque chose avec quelque chose comme ça
// TODO: anything could be here!
Edit: Je devrais dire que je voulais dire cela dans le code de production. Mais même dans le code dédié au contrôle de code source, ce n'est toujours pas bon. Mais cela pourrait être une chose personnelle dans la mesure où j'aime terminer la journée après avoir noué toutes mes extrémités :)
Edit 2: Je devrais préciser davantage ce que je voulais dire quand je vois cela dans le code établi. Comme quelque chose qui a plusieurs années et je corrige un bug. Je vois un TODO et c'est à ce moment que les sonnettes d'alarme se mettent à sonner. TODO (pour moi) implique que le code n'a jamais été terminé pour une raison quelconque.
L'utilisation du mot clé synchronized
en Java.
Non pas qu'il y ait quelque chose de mal à utiliser synchronized
quand il est utilisé correctement. Mais dans le code avec lequel je travaille, il semble que chaque fois que quelqu'un essaie d'écrire du code threadsafe, il se trompe. Je sais donc que si je vois ce mot-clé, je dois faire très attention au reste du code ...
Optimisations de judas sur du code qui pourrait être optimisé avec une meilleure structure, par exemple recherches linéaires implémentées dans l'assemblage en ligne lorsqu'une recherche binaire en C/C++/Java/C # simple serait appropriée (et plus rapide).
Soit la personne manque certains concepts fondamentaux, soit elle n'a aucun sens des priorités. Ce dernier est beaucoup plus inquiétant.
@FinnNk, je suis d'accord avec vous sur le code commenté. Ce qui me dérange vraiment, c'est des trucs comme ça:
for (var i = 0; i < num; i++) {
//alert(i);
}
ou tout ce qui était là pour les tests ou le débogage, et a été commenté puis validé. Si ce n'est qu'occasionnel, ce n'est pas un gros problème, mais s'il est partout, il encombre le code et rend difficile de voir ce qui se passe.
Tout ce qui viole des principes importants. Par exemple, quelques anti-modèles ont été suggérés (nombre magique - voir http://en.wikipedia.org/wiki/Anti-pattern ). Les anti-patterns sont appelés ainsi parce qu'ils causent des problèmes (également déjà mentionnés - fragilité, cauchemars de maintenance, etc.). Faites également attention à la violation des principes SOLID - voir http://en.wikipedia.org/wiki/Solid_ (objet-orienté_design) En outre, le code qui ne fonctionne pas 'envisager la séparation des niveaux (accès aux données à l'intérieur de l'interface utilisateur, etc.) Avoir des normes de codage et des revues de code aident à lutter contre cela.
La plupart d'entre eux proviennent de Java experience:
Lorsque le code ressemble à un gâchis: Commentaires avec "todo" et "note to self" et des blagues boiteuses. Code qui était évidemment utilisé à un moment donné uniquement à des fins de débogage, mais n'a pas été supprimé. Variables ou fonctions avec des noms qui suggèrent que l'auteur n'a pas considéré que quelqu'un le lirait plus tard. Souvent, ces noms seront très longs et difficiles à manier.
Aussi: Si le code manque de rythme. Fonctions de longueur extrêmement divergente. Fonctions qui n'adhèrent pas aux mêmes schémas de dénomination.
Légèrement lié: Cela me rend toujours nerveux si un programmeur a une écriture slobby. Ou s'ils sont de mauvais écrivains ou de mauvais communicateurs.
J'ai déjà travaillé sur un projet où l'entrepreneur avait tyepdef'f chaque type de données standard de l'int à la chaîne, y compris les pointeurs aux noms obscurs. Son approche a rendu la compréhension du code très difficile. Un autre style qui m'avertit est la flexibilité prématurée; un produit sur lequel j'ai travaillé une fois avait le code complet dans des DLL qui étaient chargées dans aucun ordre prévisible. Tout cela pour s'adapter à l'évolution future. Quelques DLL utilisaient des wrappers de threads pour la portabilité. C'était un cauchemar de déboguer le programme ou de prédire le flux en lisant le code source. Les définitions étaient dispersées dans les fichiers d'en-tête. Il n'est pas surprenant que le code n'ait pas survécu au-delà de la deuxième version.
Parfois, je vois des parties d'une méthode qui, compte tenu de toutes les entrées possibles, ne fonctionnerait JAMAIS, donc cela ne devrait pas être déroutant en premier lieu. Un exemple serait ...
Si la méthode ne peut être appelée que dans le contexte d'un superutilisateur Admin et que je vois quelque chose vérifier si l'utilisateur de la demande n'est pas un superutilisateur Admin ...: /
Commentaires mécontents démontrant un manque de retenue:
//I CAN'T GET THIS F^#*&^ING PIECE OF S$^* TO COMPILE ON M$VC
Soit ils sont de mauvaise humeur, soit ils n'ont pas assez d'expérience pour avoir appris que les revers sont inévitables dans la programmation.
Je ne veux pas travailler avec des gens comme ça.
C'est un symptôme quelque peu mineur par rapport aux choses que d'autres ont énumérées, mais je suis un programmeur Python et je le vois souvent dans notre base de code:
try:
do_something()
except:
pass
Ce qui me signale généralement que le programmeur ne savait pas vraiment (ou ne se souciait pas) pourquoi do_something
pourrait échouer (ou ce qu'il fait) - il a juste continué à "tripoter" jusqu'à ce que le code ne plante plus.
Pour ceux qui viennent d'un arrière-plan plus Java, ce bloc est l'équivalent Python de
try {
doSomething();
} catch (Exception e) {
// Don't do anything. Don't even log the error.
}
Le problème est que Python utilise des exceptions pour le code "non exceptionnel", comme les interruptions clavier ou la rupture d'une boucle for.
des getters partout me font paniquer.
et une chose spéciale: les getters délèguent à d'autres getters.
c'est mauvais parce que cela signifie que la personne qui a écrit qui ne comprend pas la base de l'orientation orientée objet, qui est l'encapsulation, ce qui signifie où se trouvent les données, les méthodes qui agissent sur ces données devraient être.
la délégation est pour une méthode pas tous les getters. le principe est "dites, ne demandez pas"; dites une chose à un objet, ne lui demandez pas mille choses et faites-le vous-même.
les getters me font flipper, car cela signifie que d'autres principes de la bêta vont être violés.
Informations de type manquantes.
Jetez un œil à ces signatures de méthode:
public List<Invoice> GetInvoices(Customer c, Date d1, Date d2)
public GetInvoices(c, d1, d2)
En (1), il y a de la clarté. Vous savez exactement avec quels paramètres vous devez appeler la fonction et le contenu de la fonction est clair.
Dans (2), il n'y a que de l'incertitude. Vous n'avez aucune idée des paramètres à utiliser et vous ne savez pas ce que la fonction renvoie si quelque chose du tout. Vous êtes effectivement obligé d'utiliser une approche inefficace par essais et erreurs pour la programmation.