He aprendido una cantidad significativa de codificación, sin embargo, siempre ha sido en un entorno científico (no informático), completamente autodidacta sin que nadie me guíe en la dirección correcta. Por lo tanto, mi viaje de codificación ha sido ... desordenado. Ahora me doy cuenta de que cada vez que construyo algún tipo de programa, al final, me doy cuenta de cómo podría haberlo hecho de manera mucho más elegante, mucho más eficiente y de una manera que es mucho más flexible y fácil de administrar en el futuro. En algunas circunstancias, he regresado y reconstruido cosas desde cero, pero por lo general esto no es prácticamente factible. Si bien la mayoría de mis programas hasta ahora han sido relativamente pequeños, parece bastante difícil reescribir completamente programas grandes cada vez que creas algo.
Me pregunto, ¿es esta una experiencia normal? Si no, ¿cómo evita que esto suceda? He intentado planificar las cosas por adelantado, pero parece que no puedo prever todo realmente hasta que empiezo a elaborar un código.
Respuestas:
Este sentimiento es completamente normal y esperado. Significa que estás aprendiendo. Casi cada vez que comienzo un nuevo proyecto, comienzo en una dirección y al final lo diseño de manera diferente.
Es una práctica común desarrollar primero un prototipo antes de comenzar con lo real. También es común volver a visitar el código antiguo y refactorizarlo . Esto es más fácil si su diseño es modular : puede rediseñar fácilmente partes y piezas a la vez sin tener que destruir totalmente su diseño anterior.
Para algunas personas, ayuda escribir pseudocódigo primero. A otros les resulta útil comenzar escribiendo comentarios que describan lo que hará el código, y luego escribir el código una vez que la estructura general esté allí. Estas dos cosas lo ayudarán a planificar mejor su diseño y podrían evitar la necesidad de una reescritura.
Si forma parte de un equipo, tener un proceso de revisión es crucial para el proceso de diseño. Pídale a alguien que revise su código para que pueda aprender cómo mejorar su diseño.
fuente
Esta es una experiencia muy común.
La mayoría de las personas con las que interactúo, y yo también, me siento así. Por lo que puedo decir, una razón para esto es que aprende más sobre el dominio y las herramientas que usa al escribir su código, lo que lo lleva a reconocer muchas oportunidades de mejora después de que ya haya escrito su programa.
La otra razón es que puede tener una idea en mente sobre la solución de código limpio ideal y luego el mundo real y sus limitaciones desordenadas se interponen en su camino, lo que le obliga a escribir soluciones y hacks imperfectos que pueden dejarlo insatisfecho.
"Todos tienen un plan hasta que los golpeen en la cara".
Qué hacer al respecto
Hasta cierto punto, tendrá que aprender a aceptar que su código nunca será perfecto. Una cosa que me ayudó con eso es la mentalidad de "Si odio el código que escribí hace un mes, significa que he aprendido y me convierto en un mejor programador".
Una forma de aliviar el problema es estar constantemente atento a posibles mejoras a medida que trabaja y refactorizar continuamente. Asegúrate de lograr un buen equilibrio entre refactorizar y agregar nuevas características / corregir errores. Esto no ayudará con grandes problemas de diseño, pero generalmente lo dejará con una base de código más pulida de la que puede estar orgulloso.
fuente
Aprenda la refactorización: el arte de mejorar gradualmente el código. Todos aprendemos todo el tiempo, por lo que es muy común darse cuenta de que el código que ha escrito usted mismo podría escribirse de una mejor manera.
Pero debería poder transformar el código existente para aplicar estas mejoras sin tener que comenzar desde cero.
fuente
Si tiene excelentes requisitos estáticos y los comprende bien y tiene tiempo para un análisis detallado, tiene la posibilidad de encontrar un buen diseño con el que todavía estará satisfecho cuando haya terminado.
Incluso en ese maravilloso caso, es posible que aprenda nuevas características del lenguaje que habrían ayudado a hacer un mejor diseño.
Sin embargo, por lo general, no será tan afortunado: los requisitos serán menos que estelares e incompletos y, aunque pensó que los entendía, resulta que hay áreas sobre las que hizo suposiciones inválidas.
Luego, los requisitos cambiarán a medida que los usuarios echen un vistazo a sus entregas iniciales. Entonces, algo que los usuarios no controlan cambiará, por ejemplo, la legislación fiscal.
Todo lo que puedes hacer es diseñar, asumiendo que las cosas cambiarán. Refactorice cuando pueda, pero tenga en cuenta que el tiempo y el presupuesto a menudo significarán que su entrega final no es tan elegante como lo hubiera sido si supiera al principio lo que sabe ahora.
Con el tiempo, mejorará al profundizar en los requisitos que recibe y conocerá qué partes de su diseño probablemente necesitarán flexibilidad para absorber el cambio.
Al final, sin embargo, acepte que el cambio es constante e ignore la punzada que dice "Podría haberlo hecho mejor". Siéntete orgulloso y feliz de haber brindado una solución.
fuente
Lo que podría hacer es crear un prototipo desechable, antes de comenzar a hacer el proyecto "real". Rápido y sucio. Luego, cuando obtienes un prototipo para probar un concepto, conoces el sistema y cómo hacer las cosas correctamente.
Pero no se sorprenda, si después de N años vuelve a este código y piensa "qué desastre".
fuente
Recuerda este mantra:
La solución perfecta no siempre es la solución ideal . La solución ideal es la que logra el estado "suficientemente bueno" con la menor cantidad de trabajo.
Si responde afirmativamente a todas estas preguntas, entonces su software es "suficientemente bueno" y no hay una buena razón para reescribirlo desde cero. Aplica las lecciones de diseño que has aprendido a tu próximo proyecto.
Es perfectamente normal que cada programador tenga un par de programas desordenados en el pasado. Sucedió varias veces durante mi carrera como desarrollador de software que miré un código, me pregunté "¿Qué idiota escribió este desastre?", Verifiqué el historial de versiones y me di cuenta de que era yo de hace varios años.
fuente
Es tentador pensar que una planificación perfecta le dará un diseño / arquitectura de software perfecto, sin embargo, resulta que es categóricamente falso. Hay dos grandes problemas con esto. En primer lugar, "en papel" y "el código" rara vez coinciden, y la razón es porque es fácil decir cómo se debe hacer en lugar de hacerlo realmente . En segundo lugar, los cambios imprevistos en los requisitos se vuelven aparentes tarde en el proceso de desarrollo que no pudieron haber sido razonados desde el principio.
¿Has oído hablar del movimiento ágil? Es una forma de pensar donde valoramos "reaccionar al cambio" en lugar de "seguir un plan" (entre otras cosas). Aquí está el manifiesto (es una lectura rápida). También puede leer sobre Big Design Up Front (BDUF) y cuáles son las dificultades.
Desafortunadamente, la versión corporativa de "Agile" es un montón de falsos (maestros de scrum certificados, procesos pesados en nombre de "Agile", forzar scrum, forzar una cobertura de código del 100%, etc.), y generalmente resulta en cambios de proceso estúpidos porque los gerentes Creo que Agile es un proceso y una bala de plata (de los cuales no lo es). Lea el manifiesto ágil, escuche a las personas que comenzaron este movimiento como el tío Bob y Martin Fowler, y no se deje engañar por la versión sin sentido de "ágil corporativo".
En particular, generalmente puede salirse con la suya haciendo TDD (Test Driven Development) en código científico , y hay una buena probabilidad de que su proyecto de software resulte bastante bueno. Esto se debe a que el código científico exitoso en su mayoría tiene interfaces ultra utilizables, con el rendimiento como una preocupación secundaria (y a veces competitiva), y por lo que puede salirse con la suya con un diseño más "codicioso". El tipo de TDD obliga a su software a ser ultra-utilizable , porque usted escribe cómo quiere que se llamen las cosas (idealmente) antes de implementarlas. También fuerza pequeñas funciones con pequeñas interfaces que pueden llamarse rápidamente de manera simple, "entrada" / "salida", y lo coloca en una buena posición para refactorizar en caso de que los requisitos cambien.
Creo que todos podemos estar de acuerdo en que
numpy
es un software informático científico exitoso. Sus interfaces son pequeñas, súper utilizables y todo funciona muy bien juntos. Tenga en cuenta quenumpy
la guía de referencia recomienda explícitamente TDD: https://docs.scipy.org/doc/numpy-1.15.1/reference/testing.html . He usado TDD en el pasado para el software de imágenes SAR (Synthetic Aperature Radar): y también puedo afirmar que funciona extremadamente bien para ese dominio en particular.Advertencia: La parte de diseño de TDD funciona menos bien en sistemas donde una refactorización fundamental (como decidir que necesita que su software sea altamente concurrente) sería difícil, como en un sistema distribuido. Por ejemplo, si tuviera que diseñar algo como Facebook donde tiene millones de usuarios simultáneos, sería un error hacer TDD (para impulsar su diseño) (todavía está bien usarlo después de tener un diseño preliminar y simplemente hacer "probar primero el desarrollo "). Es importante pensar en los recursos y la estructura de su aplicación antes de saltar al código. TDD nunca lo llevará a un sistema distribuido de alta disponibilidad.
Teniendo en cuenta lo anterior, debería ser algo evidente que un diseño perfecto es realmente imposible de lograr, por lo que perseguir un diseño perfecto es un juego tonto. Realmente solo puedes acercarte. Incluso si crees que puedes rediseñar desde cero, probablemente todavía hay requisitos ocultos que no se han mostrado. Además, las reescrituras tardan al menos el tiempo necesario para desarrollar el código original. Es casi seguro que no será más corto, ya que es probable que el nuevo diseño tenga sus propios problemas imprevistos, además de que tiene que volver a implementar todas las características del sistema anterior.
Otra cosa a tener en cuenta es que su diseño solo importa cuando cambian los requisitos .No importa cuán malo sea el diseño si nada cambia (suponiendo que sea completamente funcional para los casos de uso actuales). Trabajé en una línea de base que tenía una declaración de cambio de línea de 22,000 (la función era aún más larga). ¿Fue un diseño terrible? Diablos, sí, fue horrible. ¿Lo arreglamos? No. Funcionó tan bien como estaba, y esa parte del sistema nunca causó fallas o errores. Solo se tocó una vez en los dos años que estuve en el proyecto, y alguien, lo adivinaste, insertó otro caso en el interruptor. Pero no vale la pena tomarse el tiempo para arreglar algo que se toca con poca frecuencia, simplemente no lo es. Deje que el diseño imperfecto sea como es, y si no se rompe (o se rompe constantemente), no lo arregle. Entonces quizás podrías hacerlo mejor ... pero valdría la pena volver a escribir? ¿Qué ganarás?
HTH.
fuente
Estoy totalmente de acuerdo con la respuesta proporcionada por Andreas Kammerloher, pero me sorprende que nadie haya sugerido aprender y aplicar algunas de las mejores prácticas de codificación. Por supuesto, esto no es una bala de plata, pero usar un enfoque abierto, patrones de diseño, comprender cuándo huele su código, etc., lo convertirá en un mejor programador. Investigue cuál es el mejor uso de bibliotecas, marcos, etc. Hay mucho más seguro, solo estoy rascando la superficie.
No significa que no verá su antiguo código como una basura total (en realidad verá los programas más antiguos incluso más basura que sin este conocimiento) pero con cada nuevo software que escriba verá tu mejoras Tenga en cuenta también que la cantidad de mejores prácticas de codificación aumenta con el tiempo, algunas simplemente cambian para que nunca llegue a la perfección. Acepta esto o todo el camino.
Otra cosa buena es tener una revisión de código. Cuando trabajas solo es fácil cortar esquinas. Si tiene una segunda persona revisando su código, podrá indicarle dónde no sigue esas mejores prácticas. De esta manera, producirá un mejor código y aprenderá algo.
fuente
Para agregar a las otras excelentes respuestas aquí, una cosa que encuentro útil es saber a dónde quieres llegar .
Es raro que se le dé el visto bueno para una gran refactorización por sí solo. Pero a menudo puede hacer pequeños refactorizaciones a medida que avanza, 'bajo el radar', mientras trabaja en cada área de la base de código. Y si tiene una meta en mente, puede aprovechar estas oportunidades para moverse, paso a paso, en la dirección correcta.
Puede llevar mucho tiempo, pero la mayoría de los pasos mejorarán el código, y el resultado final valdrá la pena.
Además, ¡sentir que podrías hacerlo mejor es una buena señal ! Demuestra que te importa la calidad de tu trabajo y que lo estás evaluando críticamente; entonces probablemente estés aprendiendo y mejorando. No dejes que estas cosas te preocupen, ¡pero no dejes de hacerlas!
fuente
Inadvertidamente te has topado con uno de los mayores desafíos (aventuras) de la humanidad, el puente entre el hombre y la máquina. El puente entre el hombre y la estructura física, la Ingeniería Civil, por ejemplo, ha estado en progreso durante unos 200 años o más.
Dado que el desarrollo de software realmente solo se convirtió en la corriente principal en los años 90, tiene aproximadamente 30 años. Hemos aprendido que no se trata tanto de una disciplina de ingeniería como de una ciencia social, y recién hemos comenzado.
Sí, probará TDD, Refactorización, Programación funcional, Patrón de repositorio, Abastecimiento de eventos, MV algo, Java Script (<- Haga esto, es una locura), Enlace de modelo, Sin SQL, Contenedores, Ágil, SQL (<- haga esto es poderoso)
No hay una solución. Incluso los expertos todavía están agarrando pajitas.
Bienvenido, y ten cuidado, es un lugar solitario; pero absolutamente fascinante
fuente
Voy a ir un poco contra la corriente. Esto es increíblemente común , pero no es aceptable . Lo que esto indica es que no estás reconociendo buenas formas de organizar tu código mientras lo escribes. La sensación proviene de que su código no es sencillo .
Su experiencia también fue mía durante mucho tiempo, pero recientemente (en los últimos dos años), he estado produciendo más código que no me hace sentir que necesito tirar todo. Esto es más o menos lo que hice:
Mi código ahora es más "procesal", con lo que quiero decir que está organizado por las acciones que toma en lugar de las estructuras de datos que usa. Utilizo objetos en lenguajes donde las funciones independientes no se pueden reemplazar sobre la marcha (C # y Java no pueden reemplazar las funciones sobre la marcha, Python sí). Tengo una tendencia a crear más funciones de utilidad ahora, que simplemente eliminan algunas molestas repeticiones para poder leer la lógica de mi código. (Por ejemplo, cuando necesitaba procesar todas las combinaciones de elementos en una lista, empujé el índice a un método de extensión que devuelve
Tuple
s para que la función original no esté abarrotada con esos detalles de implementación.) Ahora paso muchas cosas más como parámetros a funciones, en lugar de hacer que una función llegue a algún otro objeto para buscarla. (La persona que llama lo busca o lo crea en su lugar y lo pasa). Ahora dejo más comentarios que explican cosas que no son obvias solo al mirar el código , lo que facilita el seguimiento de la lógica de un método. Solo escribo pruebas en casos limitados en los que me preocupa la lógica de algo que acabo de hacer, y evito usar simulacros. (Hago más pruebas de entrada / salida en piezas lógicas aisladas). El resultado es un código que no es perfecto , pero que en realidad parece estar bien., incluso 2 o 3 años después. Es un código que responde bastante bien al cambio; Se pueden agregar, eliminar o cambiar cosas menores sin que todo el sistema se desmorone.Hasta cierto punto, usted tiene que pasar por un periodo en el que las cosas son un desastre para que tenga un poco de experiencia para ir fuera de. Pero si las cosas todavía están tan desordenadas que quieres tirarlo todo y comenzar de nuevo, algo está mal; no estas aprendiendo
fuente
Al recordar que su tiempo es limitado. Y tu tiempo futuro también es limitado. Ya sea para el trabajo o la escuela o proyectos personales, cuando se trata de código de trabajo , debe preguntarse "¿reescribir este es el mejor uso de mi tiempo limitado y valioso?". O tal vez, "¿es este el uso más responsable de mi tiempo limitado"?
A veces la respuesta será inequívocamente sí . Usualmente no. A veces estará cerca y tendrás que usar tu discreción. A veces es un buen uso de tu tiempo simplemente por las cosas que aprenderás al hacerlo.
Tengo muchos proyectos, tanto laborales como personales, que se beneficiarían de un puerto / reescritura. También tengo otras cosas que hacer.
fuente
Es una parte completamente normal del aprendizaje. Te das cuenta de los errores a medida que avanzas.
Así es como se mejora y no es algo que deba evitar.
fuente
Puede darse la experiencia de saber que el impulso seductor de reescribir generalmente no es productivo. Encuentre algún proyecto de código abierto antiguo, velludo e poco elegante de complejidad moderada. Intenta reescribirlo desde cero y mira cómo te va.
Eventualmente, su instinto cambiará de pensar "podría reescribir este sistema mucho mejor" a pensar "la crudeza de este sistema puede ser indicativo de cierta complejidad que no es evidente de inmediato".
fuente