J'aimerais entendre quel type de décisions de conception que vous avez prises et comment sont-elles renversées. En raison d'une mauvaise décision de conception, j'ai fini par avoir à soutenir cette mauvaise décision (je l'ai également eu une partie). Cela m'a fait comprendre qu'une seule erreur de design peut vous hanter pour toujours. Je veux apprendre des personnes les plus expérimentées, quel type de blunders ont-ils expérimenté et que sont-ils appris d'eux.
Je suis sûr que ce sera beaucoup d'aide aux autres programmeurs en les aidant à ne pas répéter ces décisions.
Merci d'avoir partagé votre expérience.
Ignorer YAGNI , encore et encore ...
"Le fera plus tard"
[.____] "Plus tard" ne vient jamais.
C++, héritage virtuel en forme de diamant . Vous avez eu l'idée.
La configuration dans une application est agréable. Trop de configurabilité est un cauchemar à utiliser et à maintenir.
D'une de mes erreurs, j'ai appris que la normalisation DB ne devrait pas être suivie aveuglément. Vous pouvez et dans certaines situations, vous devez aplatir vos tables.
J'ai fini par gérer des charges de tables (par modèles) et les performances n'étaient pas aussi bonnes que possible avec un peu d'aplatissement pour les tables.
En utilisant un seul caractère dans des bases de données pour les statuts, etc. Pas de point dans celui-ci, la surcharge d'utilisation plus longue () ou Nvarchar2 () est minaiscule par rapport au réseau et à l'analyse engagée par n'importe quel appel SQL, mais les caractères finissent toujours up plutôt obscurci ou à court (pas pour les statuts, mais d'autres choses). De loin préférable de simplement mettre la version lisible par l'homme dans, et d'avoir également dans votre Java modèle (dans mon cas) une énumération avec des valeurs correspondantes.
Je suppose que c'est une forme d'optimisation prématurée inutile et aveugle. Comme si vous utilisez un seul caractère sauvera le monde ces jours-ci. Outre les booléens Y/N dans des bases de données qui ne supportent pas les booléens/bits.
Ne pas développer une couche appropriée couche d'accès aux données et avoir SQL partout dans mon code, juste pour obtenir quelque chose de "rapide" et de courir. Plus tard, comme le projet a commencé à se développer et que les exigences ont changé, il est devenu un cauchemar. Je ne savais pas ce qu'est un dal à l'époque.
... Je suis heureux que je puisse passer cela, même si je vois encore des programmeurs avec plus de 20 ans d'expérience de "expérience".
Pensant que je pourrais être architecte, développeur et PM tout sur le même projet.
2 mois de dormir 3 heures une nuit m'a appris que vous ne pouvez tout simplement pas le faire.
Choix des classes de la Fondation Microsoft (IFC) pour écrire A Java IDE.
Ce n'était pas -ma décision (j'ai quelque peu rejoint la société plus tard) mais quelque part que j'ai travaillé a pris un peu trop loin, y compris la traduction de tous leurs messages de journal.
Résultats:
Oups.
Réinventer la roue
faire trop de design. Créer beaucoup de diagrammes UML, en particulier des diagrammes de séquence pour chaque opération, dont une grande partie à l'extrémité s'est avérée inutile. À la fin, il s'est avéré que la quantité de temps importante aurait pu économiser en sautant inutilement des conceptions/diagrammes détaillés et de commencer directement.
Croyant que les clients savent ce qu'ils veulent et font ensuite trop avant de vérifier avec eux.
Ma seule décision de conception unique? De retour dans les années 1980, je travaillais sur un projet où nous avons eu l'idée brillante pour créer une sorte de modèle pour nos écrans de saisie de données qui seraient interprétés à l'heure d'exécution. Pas une mauvaise décision: il a fabriqué des écrans d'entrée faciles à concevoir. Fondamentalement, créez un fichier qui ressemblait à l'écran de saisie de données, avec certains codes spéciaux pour identifier ce qui était une étiquette vs ce qui était un champ de saisie et d'identifier si les champs de saisie étaient alpha ou numériques. Ensuite, j'ai décidé d'ajouter des codes supplémentaires à ces fichiers pour identifier les validations à effectuer. Ensuite, j'ai ajouté plus de codes pour permettre le bâtiment conditionnel de l'écran, champ X uniquement inclus lorsque une condition était vraie, etc. Puis j'ai ajouté plus de codes pour faire un traitement simple des entrées. Etc., etc. Finalement, nous avions transformé notre modèle d'écran en une nouvelle langue de programmation, avec des expressions, des structures de contrôle et une bibliothèque d'E/S. Et quoi pour? Nous avons fait une tonne de travail pour réinventer Fortran. Nous avons eu une étagère pleine de compilateurs pour les langues mieux conçues et mieux testées. Si nous avions consacré autant d'efforts pour créer des produits où nous avons eu une certaine expertise, cette entreprise pourrait toujours être en affaires aujourd'hui.
Application trop zélée de Yagni (appelée conception par énumération In pièges du développement orienté objet ) Dans un environnement où une personne sensible pourrait dire que les exigences étaient = définitivement aller changer. Et changer à plusieurs reprises.
Si vous avez (dur-) codé tout Exactement aux exigences actuelles - tout en battant quiconque dit "ne pouvait pas être plus générique?" Avec votre maillet Yagni, puis les exigences changent radicalement (mais d'une manière qui aurait pu être raisonnablement anticipée), cela peut alors être la différence entre la prise de 2 semaines pour s'adapter, vs prenant 20 minutes.
MISE À JOUR: Pour clarifier, voici un exemple fictif qui n'est pas trop loin de ce qui s'est passé. Le débordement de la pile a été conçu pour soutenir des badges, mais supposons qu'ils ne pouvaient penser que quatre badges au début. Seulement quatre, un tel nombre, alors ils supportent un support à code fixe pour exactement quatre badges Tout au long de la logique sur le site. Dans la base de données, dans les informations utilisateur, dans tout le code d'affichage. Parce que "tu n'aurais pas besoin de" des badges que tu ne peux pas penser, non? Supposons alors que le site va vivre et que les gens commencent à suggérer de nouveaux badges. Chaque badge prend jusqu'à deux semaines à ajouter, car il y a tellement de codage à la vitesse supérieure à peaufiner partout. Mais toujours, "tu n'aurais pas besoin de" plus de badges que la liste d'aujourd'hui, il n'y a donc jamais de refactoring pour soutenir une collection générique de badges. Une telle collection générique serait-elle prise de plus de temps à l'avant? Pas grand chose, le cas échéant.
Yagni est un principe précieux, mais cela ne devrait pas être (AB) utilisé pour excuser la mauvaise conception et le codage rigide inapproprié. Il y a un équilibre et avec l'expérience, je crois que je m'approche.
Essayer de faire quelque chose de droit et de bonne avec les mauvaises personnes!
Même si elles sont dans le rôle d'un ego superflu PM (qui est plutôt trop commun, en particulier dans les grandes entreprises où leur incompétence peut supporter une plus longue période).
Chaque fois que je crée une dette technique, écrivez un code de procédure, sautez des tests d'écriture, etc. parce que je me précipite. Presque inévitablement je trouve cela crée de la douleur pour moi sur la route.
Utilisation Services d'intergation SQL Server (SSIS).
Je ne le souhaite pas sur mon pire ennemi.
Après avoir construit plusieurs packages SSIS au cours des deux derniers mois, seul pour découvrir que les packages que j'ai développés ne sont pas distribuables et non rétablis. Spécifiquement dans un environnement agréé non-SQL Server.
C'est une très mauvaise situation d'être dans, lorsque vous avez moins de 48 heures pour ré-écrire vos packages SSIS dans le code POCO PURE .NET ou manquer votre date limite ciblée.
Cela m'ojoute que j'ai pu réécrire trois packages SSIS (qui m'a pris deux mois pour tester et développer), dans les 12 heures de code PURE .NET, avec des adaptateurs OLDED et des adapateurs SQL.
SSIS n'est pas distribuable et n'exécutera pas de packages à partir d'une machine client s'il ne dispose pas d'une licence SQL Server installée dessus (spécifiquement le DTSPIPIPENLINE.dll). Ce serait bien de savoir à l'avant. Je vois la clause de non-responsabilité maintenant (en parfait impression) sur MSDN. Cela ne fait aucun bien lorsque vous avez l'exemple de code sur Internet à l'aide de la machine sous licence SQL uniquement du code. Fondamentalement, vous devez créer un service Web qui parlera à votre serveur SQL pour exécuter vos packages SSIS par programme. Vous ne pouvez pas les exécuter à partir du code PURE .NET, sauf si vous avez une licence SQL installée sur la machine d'exécution. Dans quelle mesure est-ce irréaliste? Microsoft s'attend-il vraiment à ce que SSIS soit utilisé à partir de machines nécessitant une installation SQL Server? Quel gaspillage complet de deux mois.
Ma compagnie n'utilisera plus jamais SSIS à cause de cette petite impression "GOTCHA".
Ne définissez pas le mécanisme/modèle de déploiement le plus tôt possible.
Jeter des œufs de Pâques "drôles" dans un certain code que j'ai écrit avant de partir en vacances pendant 2 semaines. Je pensais que je serais la seule personne à la lire quand je suis rentré, ça me chercherait à rider et à être prêt à le ramener.
Inutile de dire que mon patron n'était pas impressionné lorsqu'il l'a examiné pendant que j'étais échappé, et il était encore moins impressionné lorsque l'un des "œufs de Pâques" impliquait de manière drôle cartonnée en ASCII.
Mmmmmm ...
Utilisation de thèmes ASP.NET lorsqu'il suffit d'un dossier OL 'CSS régulier aurait bien fini.
Prenant la route rapide pour obtenir du code de travail, plutôt que la route droite (binaire général, mais nous l'appellerons une abstraction et donc une réponse "droite").
Ma société a un modèle de développement semblable à la cascade, où nos utilisateurs d'entreprises et nos analystes métier définiront les exigences pour les projets. Sur l'un de nos projets "gros", nous avons eu une pile d'exigences et j'ai remarqué un certain nombre de conditions contenues Détails de la mise en œuvre , en particulier des informations relatives à notre Schéma de base de données utilisé par notre système de comptabilité.
J'ai commenté les utilisateurs d'entreprises que la mise en œuvre est mon domaine , il ne doit pas être contenu dans les exigences. Ils ne voulaient pas changer leurs exigences car, après tout, ils sont l'entreprise et il n'a aucun sens aux comptables de concevoir des logiciels comptables. En tant que développeur faible qui est trop éloigné du sondage Totem, je suis payé à DO au lieu de pense. Autant que je l'ai combattu, je ne pouvais pas les persuader de ré-écrire les exigences - il y a trop de paperasserie et de paperasserie rouges autour de changements que c'est trop nombreux.
Donc, je leur ai donné ce qu'ils ont demandé. À tout le moins, il travaille , mais la base de données est bizarre:
Beaucoup de normalisation inutile. Un seul enregistrement contenant 5 ou 10 champs est divisé sur 3 ou 4 tables. Je peux m'occuper de cela, mais j'aimerais personnellement avoir tous les champs 1: 1 tirés dans une seule table.
Beaucoup de dénormalisation inappropriée. Nous avons une table qui stocke des données de facturation qui stocke plus que des données de facturation. Nous stockons un certain nombre de drapeaux divers dans la table InvoiceData, même si le drapeau n'est pas logiquement lié à la table Infogedata, de sorte que chaque drapeau ait une valeur de clé primaire de la magie et du code principal et de tous les autres champs nulés dans la table InficeNeta. Étant donné que le drapeau est représenté comme un enregistrement dans la table, j'ai suggéré de tirer le drapeau dans sa propre table.
Beaucoup plus de dénormalisation inappropriée. Certains drapeaux d'application sont stockés sous forme de colonnes dans des tables inappropriées, de sorte que la modification du drapeau d'une application nécessite une mise à jour de chaque enregistrement de la table.
Les touches primaires contiennent des métadonnées, telles que si une clé primaire Varcharne se termine par "D", nous calculons les factures utilisant un ensemble de valeurs, sinon nous le calculons avec un autre ensemble. Il serait plus logique de tirer cette métadonnée dans une colonne séparée ou de tirer le jeu de valeurs pour calculer une autre table.
Les clés étrangères vont souvent à plus d'une table, de sorte qu'une clé étrangère se terminant par "M" puisse être liée à notre table de comptes d'hypothèque, alors qu'une clé étrangère se termine par "A" pourrait être liée à notre tableau de comptes automobiles. Il serait plus facile de diviser les données en deux tables, Mordedata et AutoInSuanceData.
Toutes mes suggestions ont été abattues avec beaucoup de gémissements et de grincements de dents. L'application fonctionne comme conçue, et tandis que sa grande boule de boue, tous les méchants hacks, des cas spéciaux et des règles d'entreprise étranges sont sarcastiquement et humorellement documentés dans le code source.
Coller à la technologie plus ancienne car il semble trop trachant pour permettre à vos clients de passer à une nouvelle version de Framework .NET, mais cela prendra en réalité plus de temps de développement pour créer le logiciel car vous ne pouvez pas utiliser de composants (à économiser) de la nouvelle version-cadre.
De retour à l'université, je travaillais sur mon projet de conception principal. Un autre gars et j'écris un système de suivi de bogues Web. (Rien novateur, mais nous voulions tous les deux avoir une expérience Web.) Nous avons fait la chose avec Java servlets, et cela a fonctionné raisonnablement bien, mais pour une raison idiote, au lieu d'opter à des exceptions En tant que notre mécanisme de traitement des erreurs, nous avons choisi d'utiliser des codes d'erreur.
Lorsque nous avons présenté notre projet pour une note et que l'une des facultés a demandé l'inévitable, "si vous deviez le refaire, que feriez-vous différemment?" J'ai instantanément connaissé la réponse: "J'utiliserais des exceptions, c'est ce qu'ils sont là pour."
Pas mon choix de méthode, mais créé un XSLT pour convertir un fichier XML basé sur une ligne dans un rapport HTML basé sur une colonne.
Cela ne fonctionnait que dans IE, était totalement impossible de décoder comment cela a fonctionné. Chaque fois que nous devions nous développer, était incroyablement difficile et pris des siècles.
En fin de compte, j'ai remplacé par un petit script C # qui a fait la même chose.
essayer d'utiliser toutes les nouvelles technologies (pour apprendre de nouvelles technologies) même s'il n'exige même pas ..
Je n'ai pas pris assez de temps pour évaluer le modèle d'entreprise. J'ai fait ce que le client a demandé, mais 6 à 12 mois plus tard, nous sommes arrivés à la conclusion que cela aurait dû faire différemment.
Concevoir sans spécification.
J'ai mis en place une sous-section d'une demande en fonction des exigences.
Il s'avère que les exigences étaient gonflées et plaquées or, et mon code était sur-conçu. J'aurais dû concevoir ma sous-section uniquement pour travailler avec ce que j'avais ajouté à l'époque, mais je prévois d'ajouter toutes les autres choses sans inclure le support générique pour cela dès le départ.
Réécrire le code de travail. HELL Le résultat fonctionne bien, il a moins de bugs et il est plus maintenu.
Mais le client pourrait se soucier de moins et cela coûte mes jours de développement ...
Essayer d'utiliser le nième élément d'un tampon circulaire [N-profond] entre 2 processeurs. Maintenant, je n'utilise jamais plus d'éléments N-1 pour le garder simple et fiable.
Le problème: un tampon circulaire ne contenant pas plus que N-1 éléments peut être réalisé complètement Threadsafe (producteur pur/consommateur). Lorsque je l'optimisée pour N éléments, la file d'attente est parfois basculée d'une perte de données complète (perte de données) ou de données vides à plein (données non valides).
Essayer de le trouver dans un système complexe (1 corruption sur 100 Mo de transfert de données) est plus difficile que de trouver une aiguille dans une foin.
Utilisation de Flash pour construire un site parce que le "designer" voulait un Carrousel de photos (c'était il y a des années, JQuery n'existait pas). Plus tard, il s'est avéré que le conçu voulait tout changer une fois par semaine, car il a changé d'avis de la conception ... Quel cauchemar de maintenance.
À mon dernier emploi, j'ai écrit des projets largiques utilisant un langage de script interne qui ne prenant pas en charge les cours, les listes et le seul mécanisme "incluent" incluant un fichier dans un autre.
Dans le recul, j'aurais pu écrire dans .net ou python et la moitié de mes problèmes d'extensibilité auraient disparu.
Couplage serré de composants qui, avec le recul, avaient très peu à faire les uns avec les autres. Les composants ont depuis été copiés-pâtes dans l'oubli par d'autres devs souhaitant utiliser une petite partie de la fonctionnalité. :-(
Écouter Joel et essayer d'étendre un logiciel au lieu de la réécriter.
Utilisation OO et polymorphisme lorsqu'une approche procédurale aurait mieux fonctionné.
quoi d'autre est pire que ça
(( a commenté les lignes problématiques, et il s'est tourné pour être l'appel de connexion. :(
A mon emploi précédent, je suis responsable de la construction d'un cadre-test automatisé. Contexte: Nous avions déjà un " prototype " qui était assez bon et a eu de nombreux tests écrits pour elle. Il a été écrit en TCL.
Pour ce nouveau projet, je devais adapter le prototype à adapter à un nouveau projet. Je détestais vraiment TCL, et venais d'apprendre Python, donc je Crient d'appliquer cette nouvelle quelque part des connaissances. Alors, bien sûr, j'ai décidé de réécrire le prototype en Python. Étant donné que nous voulions faire beaucoup de nouvelles choses vraiment cool (soutien des tests hiérarchiques mieux, ont toutes sortes de mécanismes supplémentaires pour créer facilement de nouveaux tests), je justifie ma décision en disant que l'écriture toutes ces nouvelles choses dans TCL serait un cauchemar.
En fin de compte, la plupart des nouvelles fonctionnalités (qui étaient façon trop difficile de toute façon) ont jamais été utilisés. Nous avons fini par réimplémentant l'ensemble de prototype à partir de zéro pour presque aucune récompense.
La meilleure partie? Environ un an et demi plus tard, nous avons dû trimer l'ancien prototype d'exécuter des tests sur l'ancien projet (prévisible que cela se produise). Je suis inquiet que nous aurions dû l'adapter à certains de nos nouveaux outils (une des raisons pour lesquelles je a choisi de réimplémentez en Python). Il se trouve que cela a pris environ 2 heures de travail.