Nadie es perfecto, y no importa lo que hagamos, vamos a producir código que tiene errores de vez en cuando. ¿Cuáles son algunos métodos / técnicas para reducir la cantidad de errores que produce, tanto al escribir un nuevo software como al cambiar / mantener el código existente?
30
Respuestas:
Evita la codificación elegante. Cuanto más complicado sea el código, más probable es que haya errores. Por lo general, en los sistemas modernos, el código claramente escrito será lo suficientemente rápido y pequeño.
Use las bibliotecas disponibles. La forma más fácil de no tener errores al escribir una rutina de utilidad es no escribirla.
Aprenda algunas técnicas formales para las cosas más complicadas. Si hay condiciones complicadas, asegúrelas con lápiz y papel. Idealmente, conozca algunas técnicas de prueba. Si puedo probar que el código es correcto, casi siempre es bueno, excepto por errores grandes, tontos y obvios que son fáciles de solucionar. Obviamente, esto solo llega hasta cierto punto, pero a veces puedes razonar formalmente sobre cosas pequeñas pero complicadas.
Para el código existente, aprenda cómo refactorizar: cómo hacer pequeños cambios en el código, a menudo utilizando una herramienta automatizada, que hacen que el código sea más legible sin cambiar el comportamiento.
No hagas nada demasiado rápido. Tomarse un poco de tiempo por adelantado para hacer las cosas bien, verificar lo que ha hecho y pensar en lo que está haciendo puede dar buenos resultados más adelante.
Una vez que haya escrito el código, use lo que tiene para hacerlo bueno. Las pruebas unitarias son geniales. A menudo puede escribir pruebas con anticipación, lo que puede ser una excelente respuesta (si se realiza de manera consistente, este es un desarrollo basado en pruebas). Compile con opciones de advertencia y preste atención a las advertencias.
Haz que alguien más mire el código. Las revisiones formales de códigos son buenas, pero pueden no estar en un momento conveniente. Las solicitudes de extracción o similares si su scm no las admite permiten revisiones asincrónicas. La verificación de amigos puede ser una revisión menos formal. La programación de pares asegura que dos pares de ojos miran todo.
fuente
Las pruebas unitarias le permiten reducir la cantidad de errores que aparecen por segunda vez. Si encuentra un error en su código, al escribir una prueba unitaria se asegurará de que no vuelva a aparecer más tarde. (Además, pensar en todos los casos y escribir miles de pruebas unitarias por adelantado es difícil de hacer a veces)
fuente
+1 en los dos comentarios de prueba de unidad.
Más allá de eso, establezca el nivel de advertencia más alto que ofrece su compilador y asegúrese de que las advertencias se traten como errores. Los errores a menudo se esconden en esos errores "erróneos".
Del mismo modo, invierta en herramientas de análisis estático que se ejecutan en tiempo de compilación (las veo como un nivel adicional de advertencias del compilador).
fuente
Además de lo mencionado:
Muchas otras cosas que estoy olvidando en este momento, pero las demás seguramente pensarán en ellas. :)
fuente
He desarrollado un estilo de programación bastante funcional, a pesar de que mis lenguajes principales son C ++ y Python. Descubrí que si paso todo el contexto a una función (o método) que esa función necesita para hacer su trabajo, y devuelvo los datos significativos que estoy buscando, mi código se ha vuelto mucho más robusto.
El estado implícito es el enemigo y, en mi experiencia, es la fuente número 1 de errores. Este estado puede ser variables globales o variables miembro, pero si los resultados dependen de algo que no se pasa a la función, está solicitando problemas. Claramente, no es factible eliminar el estado, pero minimizarlo tiene enormes efectos positivos en la confiabilidad del programa.
También me gusta decirles a mis compañeros de trabajo que cada rama (si, por, mientras,? :) es un error probable. No puedo decir cuál será la manifestación del error, pero cuanto menos comportamiento condicional tenga su código, más probable es que esté libre de errores simplemente debido al hecho de que la cobertura del código durante la ejecución será más consistente.
Vaya, todas estas cosas también tienen efectos positivos en el rendimiento también. ¡Ganar!
fuente
fuente
Una respuesta un poco menos técnica: no programe cuando esté cansado (9h / día es suficiente), borracho o 'horneado'. Cuando estoy cansado no tengo la paciencia necesaria para escribir código limpio.
fuente
Escribir pruebas unitarias y pruebas de integración .
fuente
Algunas excelentes respuestas aquí con respecto a las pruebas unitarias y herramientas. Lo único que puedo agregarles es esto:
Involucre a sus evaluadores lo antes posible
Si tiene un equipo de prueba, no caiga en la trampa de tratarlos como los guardianes de la calidad de su código y de detectar sus defectos por usted. En cambio, trabaje con ellos e involúcrelos lo antes posible (en proyectos ágiles, esto será desde el comienzo del proyecto, pero siempre podemos encontrar formas de involucrarlos antes si realmente lo intentamos).
Tener una buena relación de trabajo con sus evaluadores significa que puede detectar suposiciones y defectos deficientes desde el principio, antes de que puedan causar algún daño. También significa que los evaluadores se sienten capacitados para ayudar con el diseño del producto y detectar problemas de usabilidad cuando hay tiempo para solucionarlos.
fuente
Herramientas de análisis estático
Los complementos y aplicaciones como FindBugs rastrean su código y encuentran lugares donde hay errores potenciales . Los lugares donde las variables no se inicializan y usan, o simplemente son locuras que 9 de cada 10 veces, hacen que sea más fácil que surjan errores. Herramientas como esta me ayudan a evitar que mi cabeza de hueso se mueva por el camino, incluso si aún no es un error.
PD: Recuerde siempre investigar por qué una herramienta le dice que algo es malo. Nunca está de más aprender (y no todo está bien en todas las situaciones).
fuente
Inspección de código u otras formas de revisión por pares, como la programación de pares.
Las revisiones de código estructurado, como la inspección de Fagan, pueden ser al menos tan efectivas y eficientes como las pruebas unitarias e incluso han demostrado ser mejores que las pruebas unitarias en algunos casos. Las inspecciones también se pueden usar antes en el ciclo de vida del software y con artefactos distintos al código.
Peer Reviews in Software de Karl Wiegers es un gran libro sobre este tema.
fuente
Además de todas las otras sugerencias aquí, active todas las advertencias posibles al más alto nivel de sensibilidad y trátelas como errores. Utilice también cualquier herramienta de linting que tenga el idioma.
Se sorprendería de cuántos errores simples pueden ser detectados por advertencias y cuántas de esas cosas simples se traducen en errores reales en su código.
fuente
Muchas buenas respuestas aquí, pero algunas cosas que quería agregar. Asegúrese de comprender realmente el requisito. He visto muchos errores cuando el usuario pensó que el requisito significaba X y el programador pensó que significaba Y. Presione para aclarar los requisitos pobres o ambiguos. Sé que a todos nos gusta saltar y codificar, pero cuanto más tiempo pase por adelantado para garantizar la comprensión, menos reparaciones y corrección de errores habrá.
Conozca el negocio que está apoyando, a menudo verá cosas en los requisitos que faltan o que necesitan más explicaciones. Sepa que si realiza la tarea Y como se indicó, se romperá la función Z existente.
Comprenda la estructura de su base de datos. Muchos errores son el resultado de una consulta que es sintácticamente correcta, pero devuelve los resultados incorrectos. Aprende a reconocer cuándo tus resultados se ven divertidos. Si escribo una consulta de informes compleja, siempre obtengo un especialista técnico para revisar mis resultados antes de marcarlo como listo, inevitablemente verán algo en los datos que me perdí. Luego tome nota de lo que atraparon y no lo recuerde la próxima vez que haga algo similar.
fuente
Creo que la técnica más importante es tomarse su tiempo . Si siente que necesita dos días para codificar un nuevo módulo, pero su jefe lo obliga a codificar solo en un día ... es probable que su código tenga más errores.
Uno de los libros que leí hace un tiempo decía que no deberías vivir con ventanas rotas , porque a la gente no le importará si alguien se rompe ... La codificación es la misma, a todos les importará ser los primeros en hacer algo malo pero rápido , pero a ninguno le importará un código infernal , con muchos errores y un diseño y estilo muy pobres.
fuente
Sigo la práctica de Test-Code-Test en lugar de Code-test-code-test. Esto me ayuda a pensar en casos de uso y enmarcar adecuadamente la lógica.
fuente
Utilice herramientas de inspección de código como ReSharper o IDEs como IntelliJ IDEA que advierten sobre muchos errores de copiar y pegar y otros, por ejemplo, señalando variables que "se escriben, pero nunca se leen". Me ha ahorrado mucho tiempo.
fuente
Sorprendentemente, los siguientes tres puntos muy importantes aún no se han mencionado:
Use afirmaciones generosamente. La pregunta que siempre debe hacerse no es "¿debería afirmar esto?" pero "¿hay algo que olvidé afirmar?"
Opta por la inmutabilidad. (Use final / readonly liberalmente). Cuanto menos mutable tenga, menos cosas pueden salir mal.
No optimice prematuramente. Muchos programadores son ignorados por problemas de rendimiento, lo que les hace complicar innecesariamente su código y bastardar sus diseños sin siquiera saber de antemano si el rendimiento será un problema. Primero, cree su producto de software de forma académica, sin tener en cuenta el rendimiento; entonces, vea si funciona mal; (Probablemente no lo hará). Si hay algún problema de rendimiento, busque uno o dos lugares donde pueda proporcionar optimizaciones algorítmicas agradables y formales que harán que su producto cumpla con sus requisitos de rendimiento en lugar de modificar y piratear toda la base de código para apretar ciclos de reloj aquí y allá.
fuente