Notez plus de discussion sur http://news.ycombinator.com/item?id=4037794
J'ai une tâche de développement relativement simple, mais chaque fois que j'essaie de l'attaquer, je finis par une spirale de pensées profondes - comment pourrait-il prolonger l'avenir, quels seront les clients de 2e génération, comment cela affectera-t-il "non fonctionnel" aspects (par exemple, performance, autorisation ...), quelle serait la meilleure façon pour l'architecte de permettre le changement ...
Je me souviens de moi il y a quelque temps, plus jeune et peut-être plus désireux. Le "moi" que j'étais alors n'aurait pas réfléchi à tout cela - il serait allé de l'avant et aurait écrit quelque chose, puis l'a réécrit, puis l'a réécrit (et encore ...). Le "moi" aujourd'hui est plus hésitant, plus prudent.
Je trouve beaucoup plus facile aujourd'hui de m'asseoir et de planifier et d'instruire d'autres personnes sur la façon de faire les choses que d'aller de l'avant et de les faire moi-même - pas parce que je n'aime pas coder - le contraire, j'adore! - mais parce que chaque fois que je m'assois au clavier, je me retrouve dans ce même endroit ennuyeux.
Est-ce mal? Est-ce une évolution naturelle ou me suis-je entraîné dans une ornière?
Divulgation juste - dans le passé j'étais développeur, aujourd'hui mon titre de poste est "architecte système". Bonne chance pour comprendre ce que cela signifie - mais c'est le titre.
Sensationnel. Honnêtement, je ne m'attendais pas à ce que cette question génère autant de réponses. Je vais essayer de le résumer.
Les raisons:
Solutions (sans correspondance avec les raisons):
Merci à tous - je pense que le principal avantage ici a été de réaliser que je ne suis pas seul dans cette expérience. En fait, j'ai déjà commencé à coder et certaines des choses trop importantes sont tombées, naturellement.
Cette question étant close, j'accepterai la réponse avec la plupart des votes à ce jour. Quand/si cela change - je vais essayer de suivre.
Penser à ces choses est certainement une bonne chose, mais ne laissez pas cela arrêter vos progrès.
Une approche qui fonctionne vraiment bien (en particulier avec le développement itératif) consiste à implémenter une solution simple, puis à refactoriser si nécessaire plus tard. Cela maintient le code aussi simple que possible et évite la sur-ingénierie. La plupart des changements de performances ou d'architecture que vous envisagez ne seront probablement pas nécessaires de toute façon, alors ne vous embêtez pas à les écrire avant qu'ils ne soient officiellement nécessaires. Par exemple, ne vous inquiétez pas des performances jusqu'à ce qu'un profileur vous dise qu'il est temps d'améliorer les performances.
Une chose que vous pouvez faire pour vous aider à vous ajuster est de fixer une limite de temps dure sur combien de temps vous pensez à quelque chose avant d'écrire du code. La plupart du temps, le code sera meilleur si vous réfléchissez un peu, l'écrivez, réalisez vos erreurs, puis les corrigez en refactorisant.
Il y a un équilibre à trouver ici. Vous ne devriez pas simplement vous lancer tête première et ne pas penser aux conséquences, mais vous ne devriez pas non plus essayer de sur-concevoir votre code.
Wikipedia le nomme "Analyse de paralysie" dans le logiciel. La recette est de s'en tenir aux méthodologies agiles. Cela signifie que toute activité ou action individuelle a beaucoup plus de valeur qu'une tentative d'établir des pratiques ou des politiques. Chaque contributeur dans l'équipe est précieux, peu importe à quel point les capacités de la personne correspondent aux idéaux architecturaux. En agile, les individus, les ego sont les premiers, les politiques sont les derniers.
Ma réponse préférée est "L'architecture est un verbe". Arrêtez de penser, commencez à agir, peu importe à quel point vous et votre équipe vous sentirez imparfaitement et inefficacement. Peut-être que les premières actions peuvent être le démantèlement de politiques inappropriées.
Il y a 40 ans, Fred Brooks a écrit à ce sujet "Écrivez-en un à jeter, vous le ferez de toute façon." Rien n'a changé........
Est-ce mal? Est-ce une évolution naturelle ou me suis-je entraîné dans une ornière?
Ça dépend. Cela a tendance à être une étape courante sur la route d'un développeur.
Ce n'est qu'une ornière si vous restez au numéro 2.
L'une des choses que j'aime toujours garder à l'esprit est le dicton "l'avenir n'est plus ce qu'il était".
Avec une certaine expérience, il devient tentant de croire que vous pouvez prédire l'avenir, mais vous ne pouvez pas. Il est facile d'imaginer des fonctionnalités que les futurs clients/utilisateurs/tout ce qui peut vouloir, mais cela ne signifie pas qu'ils vont les vouloir tout de suite. Cela ne signifie pas non plus qu'ils vont les vouloir par-dessus une autre fonctionnalité conflictuelle. Vous devez donc vraiment limiter le temps que vous passez aujourd'hui à planifier l'avenir. Vous devez surtout limiter le temps que vous passez à construire des choses aujourd'hui qui ne seront utiles qu'à l'avenir.
La question que je pose qui me maintient sur la ligne droite et étroite est "combien sera-t-il plus difficile de construire cette fonctionnalité plus tard que de développer le support de cette fonctionnalité maintenant?" Habituellement, la réponse est que l'effort futur est à peu près le même ou peut-être deux fois ce qu'il serait de le faire maintenant. Dans ce cas, parce que je ne peux pas prédire l'avenir, je n'ai aucun problème à ne pas le construire maintenant. Si la réponse atteint 10 fois ou plus, alors je commencerai à demander quelle est la probabilité que les gens pensent que nous aurons besoin de cela au cours des deux prochaines années. Même alors, à moins qu'il n'y ait un accord généralisé, je me contenterais simplement de m'assurer qu'il n'est pas nécessaire d'annuler les choses que nous faisons aujourd'hui pour atteindre cet objectif à l'avenir.
Par exemple, j'ai travaillé sur quelques projets où nous avons passé beaucoup de temps à résumer le fait que nous utilisions Hibernate comme accès aux données plus tard. (Je n'ai jamais vu le projet construit sur Hibernate cesser de l'utiliser, donc c'était une perte de temps pour commencer, mais mettons cela de côté.) Même si cela avait été une possibilité raisonnable que nous pourrions vouloir changer plus tard, parce que nous utilisions également un modèle d'objet d'accès aux données, il n'aurait pas été plus difficile d'intégrer la flexibilité de changer Hibernate et de le changer en même temps lorsque nous en avions besoin que de créer la flexibilité dès le départ. Face à une situation comme celle-ci maintenant, je retarderais cette flexibilité jusqu'à ce que nous en ayons vraiment besoin.
À moins que vous ne fassiez de la planification stratégique pour une grande entreprise, cela ne vaut même pas la peine de penser aux problèmes architecturaux dans plus de deux ou trois ans, car la technologie évolue si rapidement. La fonctionnalité que vous envisagez de construire aujourd'hui peut être disponible gratuitement en open source dans deux ou trois ans. Il est presque certain que l'analyse coûts-avantages aura changé.
Limitez-vous à construire un système qui fait ce dont vous avez besoin aujourd'hui, dont vous êtes fier et sur lequel vous serez heureux de travailler dans quelques mois, quelle que soit la prochaine série de changements. C'est vraiment le mieux que vous puissiez faire.
Voici mon processus d'élimination personnel pour les designs incroyables qui (dans leur première version) peuvent finir par être impraticables et endommager un projet du point de vue commercial.
Et BTW, l'étape 0 est: "devenir fou avec le design". Cela m'aide à le retirer de mon système et à trouver souvent de nouvelles implications, des exigences cachées et même des fonctionnalités émergentes.
J'ai pris 1 & 2 de Rework .
Écrivez les tests. Vous avez terminé lorsque tous les tests réussissent: pas avant, et certainement pas longtemps après pendant une phase épique de suringénierie. Avoir une suite de tests pour le code que vous écrivez vous donnera un observateur indépendant et impartial vous indiquant quand vous pouvez vous arrêter.
Il n'y a que deux choses que vous devez vraiment garder à l'esprit lors de l'écriture et de la conception d'un logiciel: la maintenabilité et l'exactitude.
La correction est la plus importante à court terme et peut facilement être prouvée par des tests.
La maintenabilité aidera plus tard dans le développement mais est plus difficile à cerner.
Ma stratégie actuelle consiste d'abord à obtenir une preuve de concept monolithique, puis à séparer l'interface utilisateur du modèle (en veillant à ce que le modèle ne sache rien de l'interface utilisateur) une fois que je suis convaincu qu'elle est viable. Si j'attendais trop longtemps pour cette étape, j'obtiendrais quelque chose d'insoutenable. Si je commence par les couches séparées, je n'arrive tout simplement pas à démarrer car je suis coincé sur ce que l'interface utilisateur doit savoir sur le modèle.
Lorsque vous êtes jeune, vous ne voyez pas de risque (peut-être la raison pour laquelle les politiciens juniors sont effrayants), mais en vieillissant, vos mauvaises expériences vous paralysent à chaque occasion (peut-être la raison pour laquelle les politiciens supérieurs stagnent). Adoptez une approche guidée rasoir d'Occam - optez pour la solution qui a le moins de besoins, puis évoluez à partir de là.
Lorsque je me suis retrouvé coincé dans des situations comme celles-ci, j'ai trouvé que cela aide à imaginer obstinément que je suis un utilisateur final utilisant le programme hypothétique pour faire quelque chose d'assez trivial. Ensuite, j'essaie de me concentrer sur ce que seraient les points d'entrée programmatiques nécessaires pour soutenir ces actions, en essayant autant que possible d'ignorer d'autres aspects du système. À partir d'ici, il est souvent possible de construire une (petite!) Liste de fonctionnalités du système fini et d'écrire du code irréaliste qui démarre pour l'implémenter. Après cet exercice, je commence généralement et le reste du système commence à devenir plus clair. Il s'agit du point d'entrée - et le point d'entrée de la grande majorité de tous les logiciels sont les actions initiales des utilisateurs finaux avec un programme.
Je pense que c'est un syndrome que les tâches que vous faites sont trop faciles pour vous.
Il y a quelques années, le défi pour vous était d'écrire un code qui accomplirait la tâche donnée. C'est ce qui a pleinement engagé votre esprit. Maintenant, votre esprit (votre expérience, etc.) fonctionne plus efficacement et faire la même tâche ne nécessite qu'une partie de l'énergie qui était auparavant nécessaire. C'est pourquoi vous vous retrouvez dans cette spirale de pensées profondes. Votre esprit se défend de la routine et se bat pour le défi.
Je pense que vous devriez envisager de changer votre travail. Vous devriez peut-être apprendre un nouveau langage de programmation.
J'ai eu le même problème il y a 15 ans. Je voulais écrire un code parfait, réutilisable, universel, .... qui rendait la solution beaucoup plus compliquée que nécessaire. Aujourd'hui, je vois cela comme placage à l'or . Ce qui m'a beaucoup aidé, c'est le conseil d'un collègue:
Il s'agit simplement d'une paralysie par analyse. Cela arrive à de nombreuses personnes dans de nombreux domaines. Vous pouvez le percer.
La réponse est - CONTINUEZ JUSTE AVEC ELLE ;-)
Je poste sur un forum de remise en forme et de nombreuses fois, les gens postent sur différentes routines, essayant de trouver la parfaite parfaite pour eux. Nous leur disons donc de commencer la formation et de travailler au fur et à mesure. Vous voulez devenir plus fort, faire des exercices de force et ensuite ajuster les choses au fur et à mesure.
Lorsque vous avez un grand programme et que votre cerveau travaille des heures supplémentaires - codez d'abord les cas simples. Initialement, le programme doit s'exécuter, puis doit prendre une entrée, etc.
.
N'oubliez pas qu'à l'avenir, il est bon de refactoriser le code pour répondre à de nouvelles priorités. Vous ne pouvez pas tous les prévoir à l'avance, alors n'essayez pas.
Code pour la prochaine tâche - UNIQUEMENT. Le code est simple et bien, il est donc facile de refactoriser si vous en avez besoin. Assurez-vous que le programme fonctionne. Répéter.
Étant donné que vous devenez "coincé" en pensant à des scénarios d'utilisation possibles pour les utilisateurs finaux, il y a quelque chose à considérer ici si vous allez publier une API et vous attendre à ce que des inconnus utilisent cette API. Une fois qu'une API est publiée, vous devez soit continuer à la prendre en charge, même si vous réalisez plus tard à quel point votre première version est mauvaise, soit vous devez casser le code de tout le monde, peut-être à votre insu, qui a écrit contre elle, risquant ainsi d'aliéner eux pour tout le temps futur.
La solution standard consiste à publier en stipulant que l'API peut changer de quelque manière que ce soit à tout moment jusqu'à ce que vous ayez une idée de ce dont vos utilisateurs ont besoin et des consommateurs d'API.
Dans cette solution, je pense que c'est votre propre solution. Écrivez juste une petite chose qui fait une ou deux choses, peut-être les fait-elle juste OK, gardant la compréhension pour vous-même que tout ce que vous faites peut changer à l'avenir.
Il n'est pas possible de bien faire les choses, ou dans certains cas même N'IMPORTE QUEL des bons, quand vous commencez parce que le design est vraiment un voyage de découverte; c'est le dernier à émerger, pas la première chose à faire.
Vous ne pouvez pas concevoir une API tout de suite et ne jamais avoir à la communiquer à vos consommateurs. Vous comprenez pourquoi. De la même manière, vous ne pouvez pas écrire de logiciel et ne pas avoir à tout jeter et recommencer avec une nouvelle approche.
Je ne pense pas que vous ayez un problème dans le sens où vous avez accidentellement évolué vers quelque chose de moins créatif, productif ou souhaitable. Je pense que vous avez des normes élevées que vous appliquez accidentellement à votre situation - une erreur courante de penser que tout le monde fait.
L'expérience ne compte jamais contre vous à moins que vous ne deveniez un savoir-tout cynique, un tout-fait, et cela ressemble vraiment à l'opposé de votre situation.
J'ai quelques images que je garde en tête quand je vais grand. L'une consiste à jouer avec Lego. Je le rassemble et le démonte à volonté. Ce que je commence à faire n'est peut-être pas ce que je finis par faire. Je surfe et m'avance sur les possibilités qui me viennent à l'esprit au fur et à mesure, recréant souvent mes objectifs entièrement sur place dans un éclair d'inspiration ... c'est ça la créativité.
L'autre image est une analogie que j'ai entendue qui décrit faire de la vraie science. Vous tâtonnez dans une pièce sombre pour un chat noir qui n'est peut-être pas là. Ce n'est troublant que si vous vous considérez comme un échec pour ne pas avoir trouvé ce chat. Il n'y a pas d'autre moyen de trouver des chats noirs. C'est la seule activité qui les localise. Tout le reste est une forme d'avoir déjà ce que vous recherchez prétendument.
Vous n'en savez pas trop; vous n'en savez pas assez! Et vous ne vous en êtes rendu compte que récemment.
Ne pensez pas à vos choix de conception comme quelque chose que vous devez obtenir "bien", car il n'y a pas de "bon" - il y a beaucoup de "torts", mais il y a aussi des compromis (en vitesse d'exécution, temps pour terminer le codage tâche, extensibilité, etc.). Le code que vous écrivez, s'il est bien conçu, aura toujours diverses forces et faiblesses.
L'objectif devrait être d'arriver à un point où la compréhension de ces forces et faiblesses dans le contexte de l'utilisation et de la maintenance actuelles et futures n'est pas beaucoup plus difficile que d'écrire du code en premier lieu.
Alors n'évitez pas les pensées profondes, mais souvenez-vous que vous avez besoin d'expérience, pas seulement de réflexion, pour devenir un maître dans ce type de conception. Pensez jusqu'à ce que vous atteigniez un point où vous n'êtes pas sûr d'un choix particulier, puis mettez en œuvre ce que vous espérez être le meilleur, essayez-le et apprenez comment cela s'est passé.