¿Qué es eso de la programación defensiva?

¿Mito? ¿Una forma elegante de programar? ¿Preocupación obsesiva por los fallos?

Gerardo Fernández
Dec 4, 2019 · 8 min read

Últimamente me he topado en varios sitios con el concepto “Defensive programming” o programación a la defensiva para los hispanohablantes y como parece que es un concepto que se está poniendo poco a poco de moda he decidido preparar un artículo hablando acerca de él. Espero que os resulte interesante y que os proporcione otra visión sobre la forma en que escribís vuestro código. Es probable que muchos de los conceptos de los que aquí hablo ya os resulten familiares; la “programación defensiva” se basa en ellos para conseguir que el código sea resiliente a los fallos que se produzcan en el futuro.

Así que sin entretenernos más vamos a adentrarnos en este concepto tan interesante de la “defensive programming”.


Programación defensiva. El concepto

La programación defensiva podemos entenderla como una forma de programar en la que el desarrollador anticipa los problemas que pueden surgir en el código. Gracias a esta previsión de la que nos dota esta metodología es posible prevenir futuros fallos y, lo que es más importante, conseguir que si finalmente acaban apareciendo, el programa no falle estrepitosamente.

Es decir, la programación defensiva no se basa en la utopía de escribir código que nunca falle, sino en la premisa de que cuando nuestras aplicaciones fallen (recuerda, nadie es infalible) el error se produzca dentro de un entorno lo más controlado posible. Si la programación defensiva fuera un dicho popular estaríamos hablando de

Caer con estilo

Para lograrlo, el código que escribamos deberá:


Por qué necesitamos la “programación defensiva”

Como comentaba líneas antes, cuando escribimos código nadie es infalible y, de hecho, por mucho cuidado que pongamos siempre habrá casos extremos (los conocidos casos frontera) que no hayamos tenido en cuenta y que provocarán que nuestra aplicación falle en el futuro.

Por tanto, la programación defensiva tiene algo de pragmatismo, es decir, de ayudar a tu yo del futuro a enfrentarse a problemas que hoy no estás viendo.

Este concepto de pragmatismo es desarrollado en el libro Pragmatic Programmer de Andrew Hunt y viene a proponernos que siempre:

Realmente esta idea de “programación defensiva” puede sonarnos a obsesión pero con los años aprendes a que no hay mejor forma de irse a dormir tras subir a producción que saber que el código está protegido contra cualquier fallo que suceda.

Photo by Ben Hershey on Unsplash

Algunas pautas para seguir la programación defensiva

Ahora que ya tenemos claro lo que es la programación defensiva quiero dejaros unas pautas que os pueden ayudar a sentiros más seguros con el código que escribáis y a seguir esta idea de “defensive programming”.

👌 TDD. Test driven development

Una de las metodologías que podéis comenzar a emplear desde ya en vuestros desarrollos es TDD.

Su idea subyace en escribir siempre primero los casos de prueba unitarios para a continuación desarrollar la funcionalidad y ver si cumple las pruebas planteadas.

Por tanto, siempre tendremos una base sólida de pruebas automáticas que nos permitirán asegurarnos de que “nada se ha roto” a medida que el tamaño de nuestra aplicación crezca o refactoricemos la funcionalidad de los componentes. Si queréis, podéis pensar TDD como una metodología en la que cada componente crece en dos direcciones: funcionalidad y casos de prueba, de modo que los segundos aseguren el correcto funcionamiento del componente.

Además seguir una buena metodología TDD también nos ayudará a conseguir diseños poco acoplados pues nos obligaremos a aislar cada una de las funcionalidades cuando escribamos los casos de prueba. Esto nos permitirá tener un control mucho más detallado de cada funcionalidad y, lo que es más importante, asegurarnos de que obtenemos los resultados que esperábamos en cada llamada.

☠️ Casos frontera

Independientemente de que sigáis la metodología TDD, es importante que revisemos siempre los casos frontera de la funcionalidad que estéis escribiendo.

Por casos frontera entendemos aquellos casos que no están dentro de la funcionalidad normal del componente sino a los que puede llegarse en determinadas ocasiones.

Por ejemplo si una función espera recibir un número natural, ¿qué sucede si le enviamos un número negativo? O si estamos trabajando con campos de texto, ¿se guardan correctamente los emojis en base de datos para us posterior visualización?

Son este tipo de condiciones o casos a las que deberemos prestar más atención cuando realicemos las pruebas ya que es aquí donde suceden la mayoría de los fallos. Por tanto, no os limitéis a preparar pruebas con condiciones esperadas (algo en lo que es muy fácil caer si no somos lo suficientemente críticos con nuestro código) sino pensad en los casos rebuscados e incluso “malintencionados” pues es ahí donde podremos detectar los puntos débiles de nuestra aplicación.

🤯 Ponte siempre en lo peor

Otra forma de plantearte la programación defensiva es ponerte siempre en el peor caso. De este modo siempre estarás prevenido o alerta sobre casos que a simple vista no pueden parecer tan evidentes.

Por ejemplo, algo que me sucedió recientemente por haberme “confiado”. En el procesamiento de una llamada POST de una API todo funcionaba de forma perfecto (y pasaba todos los tests que se me habían ocurrido para esa funcionalidad) pero sin embargo, el caso más absurdo de todos provocaba fallo: un cuerpo de petición vacío.

Es por eso por lo que la programación defensiva nos insta a ir siempre con todos nuestros sentidos activos de modo que podamos anticiparnos a los futuros fallos de nuestra aplicación. Realmente, más que una metodología de trabajo como puede ser el ya mencionada TDD es una actitud ante la forma en que escribimos nuestro código con el objetivo de añadirle un extra de seguridad; es por eso que me ha resultado tan interesante: basta con tan sólo cambiar el chip para aplicarla, no se necesita ningún conocimiento especial.

🚿 Escribe código limpio

Otra de las forma en las que podemos asumir esta idea de la programación defensiva es obligarnos a escribir código limpio y optimizado, de modo que su mantenimiento y la corrección de fallos sea mucho más sencillo.

Algunos consejos que nos pueden ayudar a escribir código limpio son:


Photo by NeONBRAND on Unsplash

Conclusiones

Como ya comentaba en un párrafo anterior, todo lo que he leído acerca de la programación defensiva me ha llevado a la conclusión de que se trata de una metodología destinada a ayudarnos a anticipar los fallos, no sólo los del presente (es decir, aquellos que encontramos a medida que desarrollamos el código) sino en el futuro de modo que, cuando se produzcan, nuestra aplicación este preparada adecuadamente para responder a ellos.

¿Verdad que no hay nada más desagradable que encontrarnos con un 500 en una aplicación web con el que no contábamos en ningún momento? Es aquí donde la programación adquiere todo su sentido y por lo que conviene tenerla en mente mientras desarrollemos. Los beneficios a la larga son realmente grandes.



¿Quieres recibir más artículos como este?

Si te ha gustado este artículo te animo a que te suscribas a la newsletter que envío cada domingo con publicaciones similares a esta y más contenido recomendado: 👇👇👇

Gerardo Fernández

Written by

Entre paseo y paseo con Simba desarrollo en Symfony y React

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade