Des moyens d’empêcher une ingénierie excessive?

En développant un logiciel, je me pose souvent des questions continuelles: “Est-ce la meilleure façon?” “Y a-t-il une meilleure technologie pour le travail?” et par conséquent, j’ai mis plus d’efforts pour étudier et rechercher différents modèles / technologies / meilleures pratiques de conception que de simplement développer la chose avec des outils qui, je le sais, fonctionneront!

Une chose commune que j’ai tendance à faire est de penser trop loin et de s’inquiéter de ce qui peut arriver plutôt que de se concentrer sur les choses qui vont arriver. Je ne crois pas que ce soit nécessairement une mauvaise chose, cependant, je trouve que cela prend parfois un peu trop de temps.

J’aimerais savoir si quelqu’un d’autre a des problèmes similaires et comment s’y prendre pour les résoudre?

Adoptez une idée XP … YAGNI. ( Tu ne vas pas en avoir besoin )

Code suffisant pour résoudre ce qui doit être fait maintenant. Cela fonctionne à la satisfaction de vos clients, c’est tout ce qui compte vraiment de toute façon. Ensuite, passez à la fonction suivante.

Si vous trouvez que vous devez restructurer quelque chose, faites-le de manière incrémentielle.

Les délais

  1. fais-le fonctionner
  2. fais le mieux
  3. manquer de temps

Dans cet ordre.

Oui, j’ai vu et vécu ce problème plusieurs fois. La solution numéro un (pour moi) est un calendrier. Pas un calendrier de département marketing qui est déterminé par l’ insertion de Black Magic ici . Je parle de quelque chose comme un calendrier mensuel / sortingmessortingel que vous vous infligez à vous-même ou à votre groupe où vous dites “à cette date, nous devons avoir un projet constructible qui, s’il annulait notre projet ce jour-là, avoir quelque chose de bien. ”

Ce que cela fait est de mettre en place de véritables jalons auxquels vous devez vous engager. Rappelez-vous que les jalons sont des roches. Ils ne bougent pas. De même, le calendrier coche juste. Si vous ne pouvez pas vous engager à trouver une solution suffisamment bonne à temps, vous n’aurez rien de valable ce jour-là.

Personnellement, je pense qu’une période de trois semaines de développement + une semaine d’intégration, de test, de nettoyage et de préparation finale est un bon arrangement pour les groupes de petite et moyenne taille. Votre kilométrage variera.

Oui.

Pour éviter une ingénierie excessive, faites ceci.

  1. Construisez la chose la plus petite et la plus simple qui résout le problème.

  2. Rechercher des alternatives.

Selon mon expérience, l’expérience est le moyen le plus simple d’éviter une ingénierie excessive. Alors que les novices vont se débattre sans cesse avec leurs doutes et leurs craintes, un développeur senior le fera tout simplement. Et ils réussiront (la deuxième fois, sinon la première).

Le deuxième moyen le plus simple est la confiance. Il y a cependant un danger: sans expérience, la confiance peut être extrêmement dangereuse.

Ce qui laisse la question de savoir comment arriver avec les deux dans un court laps de temps. Les plus grands esprits du monde y travaillent. Mon chemin utilise des tests automatisés. Cela tue mes peurs et mes doutes plus rapidement que toute autre chose. Cela me permet de transférer les connaissances et l’expérience de mon cerveau à l’ordinateur, donc mon pauvre petit cerveau est libre pour la prochaine chose qui se présente et je n’ai pas à m’inquiéter de toutes les choses que j’ai déjà résolues.

Excellente question Voici ce que j’ai trouvé et ce n’est pas facile à faire:

  1. Faire des prototypes. De cette façon, je comprends mieux le problème que si je n’y pensais pas à l’avance, et je ne me suis jamais attaché à un code sous-optimal.

  2. Acquérir de l’expérience dans l’optimisation des performances de logiciels réels, car, du moins dans mon expérience, la sur-ingénierie des logiciels entraîne des problèmes de performances considérables, comme dans le cas présent . Cela vous apprend quelles approches de conception typiques conduisent simultanément à la complexité et à la lenteur, de sorte que vous pouvez les éviter. Un exemple est la trop grande importance accordée aux subtilités des classes, de la structure des données et du style axé sur les événements.
    (C’est le contraire de l’optimisation prématurée, dans laquelle en essayant de résoudre des problèmes qui n’existent pas, vous finissez par créer des problèmes.)

  3. À certains moments, j’ai adopté une vision très intransigeante de la simplicité des logiciels, et cela a eu le coût d’être très étrange, semble-t-il, pour tout le monde, sauf pour moi. Par exemple, je suis tombé sur la technique de l’ exécution différentielle , qui raccourcit le code de l’interface par un ordre de grandeur et le rend très facile à modifier, tout en créant une courbe d’apprentissage que peu de gens ont atteinte.

Libération anticipée, sortie souvent

Même si vous ne communiquez pas à un client externe, vous pouvez toujours avoir des versions internes à un propriétaire de produit ou à des testeurs. Ce type de cycle de travail vous permet de vous concentrer davantage sur la tâche à accomplir et non sur le futur.

Pratiquez YAGNI (vous n’en aurez pas besoin) et votre productivité pourrait augmenter. Probablement beaucoup.

Vous voudrez peut-être lire The Duct Tape Programmer , mais faites preuve de jugement lorsque vous le faites.

Le développement et le refactoring pilotés par les tests signifient que vous n’avez pas besoin d’avoir la meilleure approche possible, ni même de voir comment tous les détails s’intègrent entre eux… il s’agit d’ un design émergent .

En lisant les idées qui sous-tendent cela, vous pourriez vous soucier moins du perfectionnisme: http://c2.com/cgi/wiki?EmergentDesign

Voici comment j’ai appris à le faire:

  • Apprenez à écrire le test en premier pour une fonctionnalité simple.
  • Ensuite, écrivez le code qui satisfait au test.
  • Recherchez des éléments de répétition ou des choses que vous pouvez simplifier. AVANT d’essayer de simplifier / non dupliquer le code, assurez-vous de TOUT le test réussi afin d’avoir une base de référence pour le refactoring.
  • Après le refactoring, exécutez à nouveau tous les tests – pour vous assurer que vous n’avez pas modifié les comportements qui vous intéressent.
  • Vérifiez-le.
  • Répétez … jusqu’à ce que vous ayez fini …

  • C’est plus facile à faire quand on est avec quelqu’un d’autre … de préférence quelqu’un qui sait déjà faire XP.

  • Après un certain temps, vous apprenez à vous faire confiance et à accepter que vous n’avez pas besoin de contrôler tous les éléments de la solution dans les moindres détails.

En d’autres termes, apprendre XP 😉

Engagez un groupe d’architectes logiciels pour former un comité chargé d’parsingr tous les modèles.

Les conceptions seront soumises en UML pour faciliter l’parsing.

Tous les projets utiliseront tous un langage interne basé sur XML pour éviter les spécificités d’un seul langage.

Vous aurez également besoin de normes de codage détaillées pour éviter les problèmes d’ingénierie. Cela ne devrait couvrir que des choses importantes comme le positionnement de {}

C’est l’une des choses qu’un examen avec vos pairs devrait aider à déterminer. Ils devraient vous faire savoir si vous allez dans les mauvaises herbes (et être en mesure de justifier cette affirmation). D’un autre côté, ils devraient également vous faire savoir si vous n’avez pas fait assez et sont en train de concevoir quelque chose de fragile et pas assez résilient pour changer ou des problèmes.

Utiliser une partie du CMMI; mesure toi

Déterminez un moyen de garder un compte courant du nombre de fois que vous avez surenginé par rapport au nombre de fois que vous êtes sous-traitant. Calculez combien de sous-ingénierie de la douleur vous coûte en moyenne. Attendez un an ou deux et regardez-le.

En y réfléchissant davantage, cela pourrait vous aider à court terme et, à long terme, vous disposerez des données nécessaires pour savoir si votre crainte de sur-ingénierie était justifiée ou non.

Il y a quelques façons de penser:

  • Concentrez-vous sur ce qui a été demandé et, si possible, rendez les exigences aussi claires que possible. Le premier peut être considéré comme passif-agressif pour certains, car faire exactement ce qui est demandé n’est pas nécessairement une pratique courante.
  • Restez dans le moment, évitez de jouer au jeu “What if”, YAGNI.
  • Time-box le travail afin qu’il ne soit pas un trou noir sucer tout le temps disponible.

Quelques autres choses à noter:

  • Évitez de vous battre pour faire le travail que vous avez fait. Le passé va restr le passé indépendamment de ce que vous faites.
  • Le code parfait pour une application est un mythe. L’ennemi d’un bon plan est le rêve du parfait.
  • Alors que certaines parsings sont bonnes, utilisez la modération pour éviter la “paralysie de l’parsing”

Vous avez besoin de deux choses: Timeboxing et Peer Review

Timeboxing est aussi simple que de dire – je vais passer N heures à rechercher la technologie pour que cela fonctionne mieux.

L’examen par les pairs signifie que vous discutez du problème avec d’autres ingénieurs intéressés.

Il semble que vous travailliez seul, ce qui rend difficile l’examen par les pairs. Je travaille dans une boutique Scrum. Une partie du processus nécessite que nous discutions de tous les correctifs et fonctionnalités, puis que nous obtenions l’accord (accord) des autres ingénieurs avant d’écrire une ligne de code. Cela équivaut à «Mesurer deux fois, couper une fois». Nous consacrons environ la moitié de notre temps à la recherche et à la planification, et l’investissement en vaut la peine.

Reste simple, stupide

Une maxime souvent invoquée lors de la discussion de la conception pour repousser les imprécisions et contrôler la complexité du développement

http://en.wikipedia.org/wiki/KISS_principle

On dirait que vous n’avez pas de chef de projet.

Vous devez voler des techniques du célèbre débogage Rubber Duck et les appliquer à la gestion de projet. Imaginez que le Rubber Duck est votre chef de projet représentant le client principal, et expliquez-lui que vous souhaitez effectuer X heures de recherche sur une nouvelle technologie ou une nouvelle architecture. Maintenant, prétendez que le Rubber Duck vous demande si vous pensez que les nouvelles fonctionnalités valent X * Y de l’argent du client, où Y est votre salaire horaire plus le coût de votre bureau et des avantages. Ensuite, le Rubber Duck vous demande si vous pensez que la nouvelle fonctionnalité vaut la peine de retarder la livraison du produit X heures.

Répondez honnêtement aux deux questions du Canard et poursuivez le développement en fonction de votre réponse.

Incidemment, vous devriez probablement demander au canard s’il se soucie de tout le temps que vous passez sur le débordement de stack.

Tant que vous atteignez votre objective de temps, investissez autant que possible. Si vous ne pouvez pas atteindre votre objective en termes de temps, n’investissez que si vous pensez qu’il est essentiel de répondre aux exigences ou si vous pensez que vous allez devoir prendre une décision impossible à corriger si vous vous trompez …

Des optimisations prématurées et la gestion de ce qui peut être un problème.

Une idée générale est de vous assurer que vous avez un code qui fait de votre mieux et que vous êtes prêt à adopter de meilleures pratiques lorsque vous les apprenez.

En général, la solution la plus simple pour résoudre les problèmes connus est généralement la meilleure. Votre code devrait cependant être capable de détecter les cas d’erreur inattendus et de les enregistrer / exposer pour que vous puissiez append une gestion plus robuste de ces cas en coin.

Je rencontre souvent ça. Si j’ai besoin de résoudre quelque chose dans un langage que j’utilise régulièrement, qui est aujourd’hui JavaScript, et je suis coincé, j’essaie de résoudre le problème en utilisant un nouveau framework. Il y a quelque chose à propos de l’utilisation d’un nouvel outil, d’une nouvelle bibliothèque de codes, même d’un navigateur que je n’utilise généralement pas, qui m’aide à surmonter le blocage psychologique lié à la tentative de le faire correctement.

L’idée de livrables supplémentaires axés sur les fonctionnalités les plus critiques du processus unifié a été conçue pour résoudre ce problème. Il faut de la discipline pour mettre en œuvre.

Dressez une liste des fonctionnalités (cas d’utilisation), définissez des priorités, choisissez la priorité la plus élevée et travaillez comme si c’était la seule fonctionnalité dont vous ayez besoin. Lorsque vous le livrez sous une forme fonctionnelle, parsingz à nouveau et sélectionnez le prochain ensemble de fonctionnalités sur lequel travailler.

  • Choisissez la solution qui fonctionne pour vous et n’essayez pas de trouver autre chose à moins d’être limité par l’actuel (Murphy: si ce n’est pas cassé, ne le corrigez pas)
  • Créez une liste de priorités et respectez-la.

Une autre approche consiste à examiner périodiquement tout ce que vous avez fait et à le réorganiser en deux: Retirez tout ce qui n’est pas nécessaire. Répétez aussi souvent que nécessaire. Rend le code plus léger pour la prochaine itération.

Cordialement

J’évite la sous-ingénierie en essayant d’équilibrer le temps passé à rechercher et à concevoir avec ce que je peux raisonnablement attendre de son utilisation et de sa durée de vie.

Disons que j’écris un utilitaire que je ne pourrai jamais utiliser, et je l’utiliserai rarement ou même juste une fois. Si j’ai le choix entre coder un tel utilitaire en Bourne Shell ou Perl en dix minutes, et prendre trois heures pour écrire une version optimisée en utilisant des algorithmes complexes et complexes en C ++ qui fonctionnent en une minute … est moins cher que mon temps.

D’autre part, j’ai écrit des composants clés de produits utilisés ou affectés par des millions de personnes depuis de nombreuses années. Dans de tels cas, il a été utile de consacrer beaucoup de temps à la recherche, à la recherche et à la conception, à utiliser les meilleurs outils et techniques, puis à peaufiner le code.

Il n’y a pas de moyen de faire cela – tout est jugement. Et comme pour toute question de jugement, l’expérience est très utile, comme Aaron Digulla l’a justement souligné.

Lorsque j’ai débuté en tant que développeur de logiciels professionnels il y a vingt-quatre ans, je ne savais pas comment prendre ces décisions. J’écrirais juste du code, et si c’était trop lent ou trop bogué ou quelque chose, j’y retournerais et le réparerais. Mais quand j’ai fait ce correctif, j’essayerais de réfléchir à la façon dont j’aurais pu éviter le problème en premier lieu et comment je pourrais l’appliquer à l’avenir. Et j’ai aussi essayé d’écouter d’autres programmeurs quand ils parlent des problèmes qu’ils ont rencontrés et de la façon dont ils les ont corrigés.

Maintenant, plusieurs dizaines de projets et peut-être des millions de lignes de code plus tard, il y a beaucoup de décisions de conception que je peux prendre de manière presque instinctive. Par exemple: “Si vous travaillez en C ++ et que vous rencontrez un problème que certains modèles STL vont résoudre, et que vous n’êtes pas obligé d’éviter l’utilisation de STL, c’est la solution. hautement optimisé, et toute amélioration que vous pourriez obtenir en écrivant votre propre code ne vaut tout simplement pas la peine. ”

Je peux aussi regarder une situation et dire: «Les 10% de projets susceptibles d’être problématiques sont ici, et ici, et ici, nous devons concentrer nos efforts de recherche et de conception. les 90% restants, il suffit de le faire fonctionner mais nous pouvons le faire. ” Et ça marche plutôt bien.

Continuez à coder, continuez à améliorer votre code et continuez à apprendre des autres développeurs de logiciels et de votre propre expérience. Si vous continuez à prêter attention et à penser à quelque chose, la maîsortingse de la conception de logiciels augmentera avec le temps.

La boxe est ce que nous faisons.

Nous nous penchons sur un problème à venir pendant 3 jours et essayons certaines choses et choisissons une solution.

Après cela, exécutez-le et livrez-le tôt et souvent, après que vous ayez montré des progrès, vous pouvez refactoriser si une meilleure réponse se présente.

Le meilleur moyen que j’ai trouvé pour éviter la sur-ingénierie est de vous assurer que vous écrivez uniquement le code correspondant à la spécification que vous connaissez actuellement. Si vous avez une classe qui doit appeler un service Web et récupérer un type de données, ne prenez pas la peine d’écrire un système incroyablement robuste capable de gérer tous les cas possibles.

Cela dit, cette technique exige vraiment que vous créiez un code propre, bien écrit et facilement compréhensible, et que vous ayez besoin d’accesseurs partout. Si vous ne le faites pas, vous vous retrouverez avec un cauchemar de refactoring.

Lorsque vous écrivez du code pour satisfaire uniquement ce dont vous avez besoin au moment où vous construisez des fonctionnalités rapidement, lorsque les exigences changent, vous pouvez revenir en arrière et modifier votre code pour append les fonctionnalités manquantes. Chaque fois que vous ajoutez une nouvelle fonctionnalité, votre code va (lire: devrait) aller de mieux en mieux.

Il y a certainement des décisions de conception primordiales à prendre au début du projet, mais ces décisions sont de très haut niveau et ne devraient pas affecter votre capacité à changer selon les besoins.

En utilisant cette technique, vous voudrez prendre un moment avant d’écrire un nouveau module pour vous demander si cela est nécessaire pour l’implémentation actuelle, sinon, laissez-vous un commentaire et écrivez seulement ce qui est nécessaire.

Il y a un principe sûr à suivre: d’abord faire avancer les choses, puis être intelligent. Vous devez atteindre le premier objective, le second pas.

Il n’est pas si difficile d’éviter la sur-ingénierie, il suffit d’être pragmatique …

  1. obtenir une user story
  2. créer des cas d’utilisation à partir de la user story
  3. écrire un test unitaire pour la première caractéristique du premier cas d’utilisation
  4. implémenter la fonctionnalité
  5. refactoring si nécessaire, utilisez SRP pour fractionner des classes trop grandes
  6. passer à la prochaine fonctionnalité
  7. passer au prochain cas d’utilisation
  8. Une fois que vous avez terminé, vous pouvez append l’API (par exemple REST) ​​et la firebase database (par exemple PgSQL) à votre application (cette partie dépend du modèle de développement que vous suivez).

En utilisant TDD, vous n’avez pas besoin de planifier la hiérarchie complète des classes ou de comprendre le projet dans son intégralité, il vous suffit d’écrire un petit morceau de code ou de tester en même temps. Cela aide beaucoup en se concentrant uniquement sur les choses dont vous avez vraiment besoin …

J’expérimente actuellement l’ architecture propre , qui est très efficace avec TDD en créant des applications faciles à tester, à développer et à maintenir.