Clean Code (3): Funciones

El siguiente capítulo del libro Clean Code nos habla de cómo escribir funciones.

Lo más importante es que las funciones sean pequeñas. Deben ocupar unas pocas líneas, idealmente menos de 20. De este modo podremos verla en su totalidad de un solo vistazo y nos será más fácil diferenciar cada bloque gracias a la indentación. Si acompañamos este consejo de buenos nombres para estas funciones, como vimos en el capítulo anterior, tendremos un código limpio y entendible.

Además, las funciones deben hacer una única cosa, esto ayudará no solo a que sea más fácil nombrarlas y saber lo que hacen, sino que limitará su longitud. Para que las funciones tengan un único cometido, todos sus pasos deben tener el mismo nivel de abstracción. Si necesitamos hacer cosas adicionales, lo normal será que se extraigan estas líneas de código a su propia función y se llame a esa nueva función desde la función principal que nos ocupa.

Hay ciertos casos en los que será complicado que una función tenga un único objetivo, por ejemplo, cuando incluya un switch. Una posible solución a este problema sería utilizar el patrón Abstract Factory. Así, conseguiremos que el switch sólo aparezca una vez y podamos llamar a las funciones aprovechándonos del polimorfismo.

Otra característica muy importante para escribir mejores funciones son sus argumentos. En este caso seguimos la misma regla de siempre, cuantos menos, mejor. Si una función tiene muchos argumentos va a ser más difícil predecir qué hará con todos ellos sin entrar a leer la propia función. Del mismo modo, es más fácil equivocarse en el orden, especialmente si estos comparten tipo. Si necesitamos pasar muchos argumentos a una función, nos deberíamos preguntar si no deberían formar parte de un objeto y, de este modo, pasar el objeto completo. También debemos evitar siempre que podamos los argumentos que se utilizan como output y utilizar el propio return para devolver el resultado.

Las funciones no deben tener side effects. Este punto está muy relacionado con el primer tema que hemos tratado, las funciones deben tener un único cometido. Por ejemplo, si tenemos una función llamada comprobarContraseña, esperaremos que esta función nos diga si la contraseña es válida o no, pero nunca debería además iniciar la sesión del usuario. Esto puede causar problemas inesperados. ¿Qué ocurre si quiero comprobar la contraseña en otro caso y utilizo esta función? Volverá a conectar al usuario, causando posibles errores.

Debe haber separación Command-Query, es decir, las funciones tienen que hacer algo o responder algo, pero no ambas cosas a la vez. Por ejemplo, una función debe cambiar el estado de un objeto o devolver información sobre ese objeto, pero no las dos cosas en la misma función.

A la hora de tratar los errores es mejor lanzar excepciones que devolver códigos de error. Así podremos capturarlas en un bloque try-catch y hacer que todo el tratamiento de errores se haga en un único sitio. Además, esto es una única cosa, así que, la función que trata el error no deberá hacer otra cosa.

Por último, con el objetivo de evitar repeticiones, si estamos repitiendo unas instrucciones muchas veces, tenemos que considerar si estas pueden ser extraídas a una función propia. Evitar código duplicado es una de las claves de un código limpio.

Para resumir, las funciones tienen que ser cortas, tener buenos nombres y estar bien organizadas. Si conseguimos esto, estaremos un paso más cerca de tener un buen código ante nosotros.

Leave a Comment

Your email address will not be published. Required fields are marked *