it-swarm-es.com

¿Cómo puedo evitar sentir siempre que si reconstruyo completamente mi programa desde cero lo haría mucho mejor?

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.

92
Ashish

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 refactorizar él. 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 tirar a la basura su diseño anterior.

Para algunas personas, es útil escribir pseudocódigo primero. A otros les resulta útil comenzar escribiendo comentarios describiendo lo que hará el código, luego escriban 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.

4
asrjarratt

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 de las razones 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 haber 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úrese 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.

100

Aprenda la refactorización: el arte de mejorar gradualmente 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.

45
JacquesB

Si tiene excelentes requisitos estáticos y los comprende bien y tiene tiempo para un análisis detallado, tiene la posibilidad de que pueda llegar a 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 de lenguaje que hubieran ayudado a hacer un mejor diseño.

Sin embargo, por lo general, no tendrás tanta suerte: los requisitos serán menos que estelares e incompletos y, aunque pensaste que los entendías, resulta que hay áreas sobre las que hiciste 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á, p. ley de Impuesto.

Todo lo que puede 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.

9
Wildbill

¿Cómo puedo evitar sentir siempre que si reconstruyo completamente mi programa desde cero lo haría mucho mejor?

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".

3
BЈовић

Recuerda este mantra:

Lo perfecto es enemigo de lo bueno .

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.

  • ¿Cumple con todos los requisitos de funcionalidad y rendimiento?
  • ¿Está libre de errores críticos que no puede solucionar en la arquitectura actual?
  • Calcule cuánto trabajo invertirá para mantener esta aplicación en el futuro. ¿Sería el esfuerzo de reescribir más que el esfuerzo a largo plazo que ahorraría?
  • ¿Existe la posibilidad de que su nuevo diseño realmente empeore las cosas?

Si responde que sí 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.

3
Philipp

He intentado planificar las cosas por adelantado, pero parece que no puedo prever todo realmente hasta que empiezo a elaborar un código.

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 ¡realmente hacerlo. En segundo lugar, los cambios imprevistos en los requisitos se hacen evidentes al final del proceso de desarrollo, lo que no podría haberse razonado 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 otros 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, por lo general, produce cambios en el proceso 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 la gente ¡quién comenzó 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 bien. 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 TDD obliga a su software a ser ultra-utilizable , porque usted escribe cómo ¡quiere cosas que se llamarán ( idealmente) antes de implementarlos realmente. También fuerza funciones pequeñas con interfaces pequeñas que pueden ser llamadas rápidamente una manera simple de "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 que la guía de referencia de numpy 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 usar después tiene un = ¡preliminar diseño, y solo "prueba el primer desarrollo"). Es importante pensar en los recursos y la estructura de su aplicación ¡antes saltar al código. TDD nunca lo llevará a un sistema distribuido de alta disponibilidad.

¿Cómo puedo evitar sentir siempre que si reconstruyo completamente mi programa desde cero lo haría mucho mejor?

Dado 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 de tontos. Realmente puedes solo acércate. Incluso si piensa puedes rediseñar desde cero, probablemente hay ¡todavía requisitos ocultos que no se han mostrado. Además, las reescrituras toman ¡al menos tanto tiempo como tomó para desarrollar el código original. Es casi seguro que no será más corto, ya que es probable que el diseño ¡nuevo 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 realmente ¡cuando los requisitos cambian. No importa cuán malo sea el diseño es 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 adivinó, 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ía hacerlo mejor ... pero ¿valdría la pena reescribirlo? ¿Qué ganarás?

HTH.

3
Matt Messersmith

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.

2
Ister

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ía 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!

1
gidds

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, No SQL, Contenedores , Agile, SQL (<- hacer 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.

1
Marius

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 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 siento que necesito tirar todo a la basura. Esto es más o menos lo que hice:

  1. Sea claro sobre las suposiciones que está haciendo un bloque de código en particular. Lanzar errores si no se cumplen. Piense en esto de forma aislada , sin depender de los detalles sobre lo que está haciendo el resto del software. (Lo que está haciendo el resto del software influye en las suposiciones que aplica y en los casos de uso que admite, pero no influye si arroja un error cuando se viola una suposición).
  2. Deja de creer que seguir las reglas, patrones y prácticas producirá un buen código. Deseche las mentalidades y prácticas que no son obvias y directas. Este fue enorme. OO y TDD generalmente se enseñan de una manera que no se basa en consideraciones prácticas, como un conjunto de principios abstractos que debe seguir al escribir código. Pero esto es completamente inútil para desarrollar un buen código Si usa OO o TDD), debe usarse como soluciones a los problemas que entiende que tiene . En otras palabras, solo deben usarse cuando se observa un problema y se piensa: "Bien, esto tiene mucho sentido y es extremadamente obvio como una buena solución". No antes.
  3. Cuando estoy escribiendo código, concéntrate en dos preguntas:
    • ¿Estoy usando funciones y bibliotecas en la forma en que fueron diseñadas para usarse ? Esto incluye usarlo para los tipos de problemas que estaba destinado a resolver, o al menos muy similares.
    • ¿Es simple ? ¿Mis compañeros de trabajo y yo podremos seguir la lógica fácilmente más adelante? ¿Hay cosas que no son inmediatamente obvias por el código?

Mi código ahora es más "procesal", con lo que quiero decir que está organizado por qué acciones toma en lugar de qué estructuras de datos usa. Utilizo objetos en lenguajes donde las funciones independientes no se pueden reemplazar sobre la marcha (C # y Java no puede reemplazar las funciones sobre la marcha, Python puede). Tengo una tendencia a crear más funciones de utilidad ahora, que simplemente empujan un poco de molesto repetitivo para que pueda 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 Tuples para que la función original no se saturara con esos detalles de implementación. ) Ahora paso muchas más cosas como parámetros a funciones, en lugar de hacer que una función se acerque a otro objeto para buscarla (la persona que llama la busca o la crea y la pasa). Ahora dejo más comentarios que explican las cosas. que no son obvios solo al mirar el código , lo que hace que seguir la lógica de un método sea más fácil. Solo escribo pruebas en casos limitados donde ' estoy preocupado por 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 está 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 pasar por un período en el que las cosas son un desastre para que tenga algo de experiencia para salir. Pero si las cosas todavía están tan desordenadas que quieres tirarlo todo y comenzar de nuevo, algo está mal; no estas aprendiendo.

1
jpmc26

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 trabajo código, debe preguntarse "¿reescribir esto es el mejor uso de mi tiempo limitado y valioso?". O tal vez, "¿es este el más responsable uso de mi tiempo limitado"?

A veces la respuesta será inequívocamente . 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.

0
Jared Smith

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.

0
mathreadler

Puede darse la experiencia de saber que el impulso seductor de reescribir generalmente no es productivo. Encuentre un proyecto de código abierto antiguo, velludo e poco elegante de complejidad moderada Intenta reescribirlo desde cero y mira cómo te va.

  • ¿Su diseño desde cero terminó tan elegante como esperaba?
  • ¿Es su solución realmente al mismo problema exacto? ¿Qué características omitiste? ¿Qué casos de Edge te perdiste?
  • ¿Qué lecciones duramente ganadas en el proyecto original borraste en la búsqueda de la elegancia?
  • Después de agregar esas piezas faltantes a su diseño, ¿está tan limpio como lo estaba sin ellas?

Con el tiempo, 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".

0
Maxpm