Si le preguntas a los programadores por qué deberían escribir código limpio, la respuesta número uno que obtienes es la mantenibilidad. Si bien eso está en mi lista, mi razón principal es más inmediata y menos altruista: no puedo decir si mi nuevo código es correcto si está demasiado sucio. Me parece que me he centrado tanto en las funciones individuales y en las líneas de código que cuando termino mi primer borrador y retrocedo para volver a ver el panorama general, a veces no encaja muy bien. Pasar una o dos horas refactorizando la limpieza con frecuencia descubre errores de copiar / pegar o condiciones de límites que eran muy difíciles de detectar en el borrador.
Sin embargo, algunas personas sienten que ocasionalmente está bien revisar intencionalmente el código sucio en interés del envío de software, con un plan para "limpiarlo más tarde". ¿Existe alguna técnica practicable que les dé confianza en la exactitud de su código cuando la legibilidad es menos que ideal? ¿Vale la pena intentar desarrollar una habilidad? ¿O la falta de confianza en el código es algo que algunas personas encuentran más fácil de aceptar?
How do quick & dirty programmers know they got it right?
Porque funciona :)Respuestas:
El código probablemente no sea correcto.
Sin embargo, puede que no importe.
Rápido y sucio puede ser el camino correcto en situaciones donde:
A veces no es importante que el código sea robusto y maneje todas las entradas imaginables. A veces solo necesita manejar los datos conocidos que tiene a mano.
En esa situación, si las pruebas unitarias te ayudan a escribir el código más rápido (este es el caso para mí), entonces úsalos. De lo contrario, codifique rápido y sucio, haga el trabajo. Los errores que no se activan no importan. Los errores que corrige o soluciona sobre la marcha no importan.
Lo que es absolutamente vital es que no diagnostique mal estas situaciones. Si codifica rápido y sucio porque el código solo se usará una vez, entonces alguien decide reutilizar el código en algún proyecto que merezca un código mejor, ese código mereció más cuidado.
fuente
Ellos no. Actualmente estoy trabajando en una base de código creada por programadores "rápidos y sucios" que la "limpiarían más tarde". Se han ido hace mucho tiempo, y el código sigue vivo, crujiendo hacia el olvido. Los codificadores Cowboy , en general, simplemente no entienden todos los modos de falla potenciales que puede tener su software, y no entienden los riesgos a los que están exponiendo a la empresa (y sus clientes).
fuente
De acuerdo, a riesgo de ser un completo cebo de votos negativos, voy a "defender a los demonios" la opinión contraria.
Propongo que los desarrolladores tengamos una tendencia a preocuparnos demasiado por cosas como la práctica adecuada y la limpieza del código. Sugiero que, si bien esas cosas son importantes, nada de eso importa si nunca envía .
Cualquiera que haya estado en este negocio por un tiempo probablemente estaría de acuerdo en que sería posible jugar con un software de forma más o menos indefinida. Duke Nukem Forever, mis amigos. Llega un momento en que esa característica agradable o ese trabajo de refactorización tan urgente solo debe dejarse de lado y la cosa debe llamarse HECHO.
He peleado con mis colegas sobre esto muchas veces. SIEMPRE hay un ajuste más, algo más que "debería" hacerse para que sea "correcto". SIEMPRE puedes encontrar eso. En algún momento, en el mundo real, lo suficientemente bueno solo tiene que ser lo suficientemente bueno. Ningún software de envío real en el mundo real es perfecto. Ninguna. En el mejor de los casos, es lo suficientemente bueno.
fuente
Tales programadores casi nunca saben que lo hicieron bien, solo lo creen . Y la diferencia puede no ser fácil de percibir.
Recuerdo cómo solía programar antes de aprender sobre las pruebas unitarias. Y recuerdo ese sentimiento de confianza y confianza en un nivel completamente diferente después de ejecutar mi primer conjunto de pruebas de unidad decente. No sabía que existía tal nivel de confianza en mi código antes.
Para alguien que carece de esta experiencia, es imposible explicar la diferencia. Por lo tanto, incluso pueden seguir desarrollándose en modo de código y oración a lo largo de su vida, creyendo benevolentemente (e ignorantemente) que están haciendo su mejor esfuerzo teniendo en cuenta las circunstancias.
Dicho esto, de hecho puede haber grandes programadores y casos excepcionales, cuando uno realmente logra mantener todo el espacio del problema en su mente, en un estado completo de flujo. He experimentado momentos raros como este, cuando sabía perfectamente qué escribir, el código se me escapaba sin esfuerzo, podía prever todos los casos especiales y las condiciones límite, y el código resultante simplemente funcionaba . No tengo dudas de que hay genios de la programación que pueden permanecer en ese estado de flujo durante períodos prolongados o incluso la mayor parte de su tiempo, y lo que producen es un código hermoso, aparentemente sin esfuerzo. Supongo que esas personas tal vez no sientan la necesidad de escribir pruebas unitarias insignificantes para verificar lo que ya saben.. Y si realmente eres un genio, puede estar bien (aunque incluso así, no estarás cerca de ese proyecto para siempre, y debes pensar en tus sucesores ...). Pero si no...
Y seamos sinceros, es probable que no lo seas. Yo, por mí mismo, sé que no lo soy. Tuve algunos momentos raros de flujo, e incontables horas de dolor y tristeza, generalmente causadas por mis propios errores. Es mejor ser honesto y realista. De hecho, creo que los mejores programadores son plenamente conscientes de su propia falibilidad y errores pasados, por lo que han desarrollado conscientemente el hábito de verificar sus suposiciones y escribir esas pequeñas pruebas unitarias, para mantenerse a salvo. ( "No soy un gran programador, solo un buen programador con buenos hábitos" - Kent Beck).
fuente
Pruebas unitarias . Es la única forma de tener confianza en cualquier código (sucio o no).
En otros comentarios;
fuente
Es bueno aprender a aceptar que ningún sistema de software de complejidad razonable será perfecto, independientemente de la cantidad de pruebas unitarias y ajustes de código que se realicen. Algún grado de caos y vulnerabilidad a lo inesperado siempre acechará dentro del código. Esto no significa que uno no deba intentar producir un buen código o realizar pruebas unitarias. Estos son, por supuesto, importantes. Hay que buscar un equilibrio y esto variará de un proyecto a otro.
La habilidad que se debe desarrollar es comprender qué nivel de "perfección" se debe utilizar para un proyecto en particular. Por ejemplo, si está escribiendo una solicitud de registros médicos electrónicos con un cronograma del proyecto de 12 meses, querrá dedicar mucho más tiempo a las pruebas y asegurarse de que su código sea mantenible de lo que lo haría para una aplicación web de registro de conferencia única eso tiene que ser implementado para el viernes. Los problemas llegan cuando alguien que hace la aplicación EMR se vuelve descuidado o la aplicación de registro no se implementa a tiempo porque el programador está demasiado ocupado ajustando el código.
fuente
Rápido y sucio está perfectamente bien dentro de un subsistema . Si tiene una interfaz bien definida entre su basura y el resto del sistema, y un buen conjunto de pruebas unitarias que verifican que su código feo, rápido y sucio hace lo correcto, puede estar perfectamente bien.
Por ejemplo, tal vez tenga algún truco horrible de expresiones regulares y desplazamientos de bytes para analizar algunos archivos que provienen de un tercero. Y suponga que tiene una prueba que dice que el resultado que obtiene al analizar archivos de ejemplo es lo que espera. Podría limpiar esto para poder ... No sé, ¿reaccionar más rápidamente cuando un tercero cambia un formato de archivo? Eso simplemente no sucede con la suficiente frecuencia. Es más probable que cambien a una API completamente nueva y deseche el analizador anterior y conecte uno nuevo que se ajuste a la misma API, y listo, ya está.
Donde lo rápido y sucio se convierte en un problema es cuando su arquitectura es rápida y sucia. Su objeto de dominio central debe estar bien pensado y sus interfaces, pero los bordes de su sistema generalmente pueden ser desordenados sin tener que pagar el precio.
fuente
Aquí hay una historia sobre un programador rápido y sucio que conozco.
Conozco a una persona que considera que las pruebas unitarias son una pérdida de tiempo. Después de mucho argumento, finalmente escribió uno. Consistía en un método largo rociado con && y || y devolvió un booleano para afirmar True. La declaración abarca 20 líneas. Por otra parte, escribió una clase donde cada método tenía una línea y la principal tenía más de 1000 líneas sin espacios en blanco. Era un muro de texto. Cuando revisé su código e inserté algunas líneas nuevas, me preguntó "por qué". Dije 'Debido a la legibilidad'. Suspiró y los borró. Puso un comentario en la parte superior "¡No lo toques, funciona!"
La última vez que hablé con él, codificó un sitio web para una empresa. Estaba tratando de encontrar un error. Había pasado los últimos 3 días haciendo eso durante 8 horas al día. Un poco más tarde volví a hablar con él, y resultó que su compañero de equipo cambió el valor de un literal y no lo actualizó en otro lugar. No fue una constante. Así que también cambió los otros literales para que su error se solucionara. Se quejó del código de espagueti de su compañero de equipo. Me dijo 'Jaja, ¿no todos sabemos lo que es estar despierto toda la noche con el depurador, sin dormir un solo error desagradable? "Él piensa que esto es algo que hacen realmente los buenos programadores y realmente se siente bien al respecto.
Además, piensa que leer libros de programación y blogs es inútil. Él dice, 'solo comienza a programar'. Lo ha hecho durante 12 años y cree que es un excelente programador. / facepalm
Aquí hay más.
Otra vez estábamos escribiendo una clase de DatabaseManager para nuestra aplicación web. Puso todas las llamadas a la base de datos. Era una clase de Dios con más de 50 métodos para cada cosa imaginable. Sugerí dividirlo en subclases porque no todos los controladores necesitan saber acerca de cada método de base de datos. No estuvo de acuerdo, porque era "fácil" tener una sola clase para toda la base de datos y era "rápido" agregar un nuevo método cuando lo necesitábamos. Al final, DatabaseManager tenía más de 100 métodos públicos, desde autenticar al usuario hasta clasificar las ubicaciones de los sitios arqueológicos.
fuente
Mi lección para evitar lo rápido y lo sucio fue cuando tuve seis meses para entregar lo que se estimó (subestimado) como un año de trabajo. Decidí investigar metodologías antes de comenzar a trabajar. Al final invertí tres meses de investigación y pude entregar en los tres meses restantes.
Obtuvimos grandes ganancias al identificar funcionalidades comunes y construir las bibliotecas requeridas para manejar esos requisitos. Todavía veo codificadores que escriben su propio código cuando hay rutinas de biblioteca disponibles. Estos codificadores a menudo reescriben, o, en el mejor de los casos, cortan y pegan, el mismo código cuando necesitan resolver el mismo problema más adelante. Las correcciones de errores invariablemente solo capturan algunas de las copias del código.
Un desarrollador dio una respuesta contundente cuando le pedí que usara el código de la biblioteca: "¿No es una trampa? Tuve que escribir todo mi propio código en la escuela".
fuente
En algunos casos, supongo que podría haber un gran conjunto de pruebas de regresión que encontrarán "todos" los errores y verificarán el comportamiento, lo que permitirá una técnica de codificación rápida y sucia. Pero sobre todo es solo una cuestión de mala planificación del proyecto y un gerente que cree que es más importante hacerlo bien que hacerlo bien.
Y olvídate de "limpiarlo más tarde", eso nunca sucede. En los raros casos en que sucede, el programador habrá olvidado la mayor parte del código, lo que hace que el trabajo sea mucho más costoso que si lo hubiera hecho bien la primera vez.
fuente
El producto se envía.
El código no existe en el vacío. He sufrido un dolor indescriptible por las consecuencias de la codificación rápida, sucia y vaquera. Pero a veces terminar el producto es la prioridad, no descubrir cómo escribir el mejor código. En última instancia, si el producto se envía y funciona lo suficientemente bien, los usuarios y los clientes no sabrán ni se preocuparán por lo "malo" que sea el código en su interior, y admitiré que hubo momentos en que no me importó en absoluto "obtenerlo bien "siempre que lo saque por la puerta.
Sí, esto en un problema de organización y "nunca debería suceder". Pero si usted está escribiendo código en una organización que está mal administrada y está muy sujeta a plazos, a nivel de programador individual, las opciones son limitadas.
fuente
No creo que puedan decir honestamente que lo hicieron bien si no es fácil de mantener. Si admiten que tienen que "limpiarlo más tarde", entonces es probable que haya algo que no hayan pensado lo suficiente. Probarlo a fondo solo descubrirá realmente cualquier problema con el código sucio.
Yo personalmente no trataría de desarrollar la habilidad de "escribir código sucio" y tener confianza en su corrección. Prefiero escribir el código apropiado la primera vez.
fuente
¿Cómo saben que lo hicieron bien? La prueba es la respuesta simple.
Si su código ha sido probado exhaustivamente por un buen equipo de control de calidad y pasa, entonces diría que lo hicieron bien.
Escribir código rápido y sucio no es algo que deba hacerse como un hábito, pero al mismo tiempo hay ocasiones en las que puede pasar 20 minutos escribiendo código que puede clasificarse como sucio o 4 horas refactorizando mucho código para hacerlo bien. En el mundo de los negocios, a veces 20 minutos es todo lo que está disponible para hacer el trabajo y, cuando se enfrentan a plazos, puede ser la única opción rápida y sucia.
Yo mismo he estado en ambos extremos de esto, tuve que arreglar el código sucio y tuve que escribir el mío para evitar las limitaciones de un sistema en el que estaba desarrollando. Diría que tenía confianza en el código. escribí porque, aunque estaba sucio y era un poco hackeado, a veces me aseguré de que se probara a fondo y tuviera una gran cantidad de errores incorporados, por lo que si algo salía mal no destruiría el resto del sistema.
Cuando menospreciamos a estos programadores rápidos y sucios, debemos recordar una cosa, un cliente generalmente no paga hasta que tiene el producto, si se envía y entra en pruebas UAT y encuentra los errores del código rápido y sucio, es un es mucho menos probable que se retiren cuando tengan un producto casi funcional frente a ellos, sin embargo, si no tienen nada y usted les dice "lo tendrá pronto, solo estamos reparando x" o "se retrasó porque tuvimos que obtener y trabajando perfectamente ", es más probable que se den por vencidos y se vayan con un competidor.
¡Por supuesto, como esta imagen demuestra que nadie debe subestimar el peligro de un código rápido y sucio!
fuente
No creo que debas comenzar a seguir ese camino. Rápido y sucio puede darle el beneficio temporal de terminar más rápido, pero al final siempre paga diez veces por hacer esto.
fuente
En mi opinión, aprender a juzgar si el código Q&D es correcto no es una habilidad que valga la pena desarrollar porque es una mala práctica. Este es el por qué:
No creo que "rápido y sucio" y "mejores prácticas" vayan de la mano. Muchos codificadores (incluido yo mismo) han creado código rápido y sucio como resultado de un sesgo en las restricciones triples . Cuando tuve que hacerlo, generalmente fue el resultado de un aumento de alcance combinado con una fecha límite cada vez más próxima. Sabía que el código que estaba registrando era malo, pero escupía las salidas adecuadas dado un conjunto de entradas. Muy importante para nuestros grupos de interés, enviamos a tiempo.
Una mirada al Informe CHAOS original deja bastante claro que Q&D no es una buena idea y matará el presupuesto más tarde (ya sea en mantenimiento o durante la expansión). Aprender a juzgar si el código de preguntas y respuestas es correcto es una pérdida de tiempo. Como dijo Peter Drucker, "No hay nada tan inútil como hacer eficientemente lo que no se debe hacer en absoluto".
fuente
"Sucio" significa cosas diferentes para diferentes personas. Para mí, en su mayoría significa confiar en cosas en las que sabes que probablemente no deberías confiar, pero que también sabes que puedes esperar para trabajar a corto plazo. Ejemplos: suponiendo que un botón tiene 20 píxeles de altura en lugar de calcular la altura; codificar una dirección IP en lugar de resolver un nombre; contar con una matriz que se ordenará porque sabe que es así, aunque el método que proporciona la matriz no lo garantiza.
El código sucio es frágil: puede probarlo y saber que funciona ahora , pero es una buena apuesta que se romperá en algún momento en el futuro (o de lo contrario obligará a todos a caminar sobre cáscaras de huevo por miedo a romperlo).
fuente
A riesgo de sonar un poco controvertido, diría que nadie SABE realmente que su código es 100% correcto y 100% sin error. Incluso cuando tenga una cobertura de prueba realmente buena y esté aplicando rigurosamente las buenas prácticas de BDD / TDD, aún puede desarrollar código que contenga errores, ¡y sí, que incluso puede contener efectos secundarios!
Solo escribir código y suponer que funciona implica un exceso de confianza por parte del desarrollador sobre las propias habilidades de ese desarrollador, y que cuando surgen problemas (lo que inevitablemente ocurrirán) el esfuerzo para depurar y mantener el código será costoso, especialmente si otro desarrollador necesita para mantener el código más adelante. La verdadera diferencia se hace mediante la aplicación de buenas prácticas de ingeniería de software, que aseguran que puede tener la verdadera confianza de que su código probablemente funcionará la mayor parte del tiempo, y que si encuentra un error, es más probable que sea más fácil de depurar y mucho menos costoso de cambiar y mantener independientemente de la persona que trabaje en ese código más adelante.
Lo más destacado es que un código bien factorizado y probado permitirá a OTROS tener confianza en su código, que en la mayoría de los casos es más importante que su propia confianza.
fuente
Si el código sucio está bien probado, se puede confiar. El problema es que esa unidad que prueba el código sucio suele ser muy difícil y engorrosa. Es por eso que TDD es tan bueno; Revela y elimina la suciedad y los olores. Además, las pruebas unitarias son a menudo lo primero que sufre la falta de tiempo. Entonces, si el tipo más limpio alguna vez hizo el código más limpio que jamás haya hecho, aún no confiaría en nada, si omitiera las pruebas unitarias debido a la falta de tiempo.
fuente
Los buenos programadores (Quick & Dirty y otros) no tienen la arrogancia de asumir que lo han hecho bien. Asumen que todos los sistemas grandes tienen errores y fallas, pero que en algún momento podrían probarse y revisarse lo suficientemente bien como para tener un riesgo suficientemente bajo o un costo de falla lo suficientemente bajo como para que el código pueda enviarse.
Entonces, ¿por qué existen estos, llamados programadores Quick & Dirty,? Mi hipótesis es la selección darwiniana. Los programadores que envían códigos viables rápidamente, ocasionalmente envían antes de que la competencia se envíe, o el presupuesto se agote, o la empresa quiebre. Por lo tanto, sus empresas todavía están en el negocio empleando nuevos programadores para quejarse del desorden que debe limpiarse. Los llamados códigos limpios también se envían, pero no lo suficientemente bien como para llevar a los codificadores Quick & Dirty a la extinción.
fuente
Probablemente se pueda pensar que una parte no óptima de un código no puede hacer ninguna diferencia, debido a la corta vida útil, el poco impacto en los negocios o el poco tiempo para hacerlo. La respuesta correcta es que realmente no lo sabes. Cada vez que escucho a alguien decir que "esta es una característica pequeña" o "hagámoslo lo más rápido y simple posible" y no dedico suficiente tiempo a pensar en el diseño correcto, las dos únicas cosas que realmente ocurren son:
1-) El proyecto se hace más grande y la motivación del equipo baja, trabajando en un código lleno de "puntos". En ese caso, el proyecto probablemente se convierta en un camino rápido hacia el caos.
2-) Se sabe que el proyecto es una solución no óptima y su uso comienza a desalentarse, en favor de una nueva solución o una refactorización que es tan costosa como una nueva solución.
Intenta siempre hacer el mejor código que puedas. Si no tiene suficiente tiempo, explique por qué necesita más. No te arriesgues con un trabajo mal hecho. Sé siempre un mejor profesional. Nadie puede castigarte por esto si eres razonable. Si lo hacen, no es donde debería trabajar.
fuente
Discuta con el superior y evalúe el impacto de las fallas, si las hay. Por ejemplo, una situación en la que puede reparar la suciedad tarda 1 día y un código robusto requiere un cambio de diseño y arquitectura que puede llevar de 4 a 6 meses + tiempo de validación adicional para validar por completo todos los flujos de trabajo que se vieron afectados por el cambio de diseño.
También tenemos que tomar una decisión basada en Tiempo + Capacidad + Prioridades en la lista. Una buena discusión en el equipo con personas de la tercera edad o personas con mayor experiencia puede ayudar a llegar a una decisión que se ajuste mejor al equipo y su entrega.
El código limpio es el primer y más importante enfoque en el que, como código sucio para salvar las escaladas, las decisiones ir / no ir de los clientes, mostrar tapones, la reputación de la organización en juego y muchos más, donde el código sucio se convierte en código limpio.
fuente