Clean Code en Frontend
Hablemos de Clean Code, que no es más que un "código limpio". Para muchos desarrolladores, tener un código limpio significa escribir la menor cantidad de líneas posible.
Pero esto no es del todo cierto. El verdadero valor de Clean Code está en escribir código que sea fácilmente comprensible tanto en estructura como en función, conciso y que no pueda interpretarse de muchas maneras.
¿Realmente necesitamos un Clean Code?
Por supuesto, cuando lo llevamos a un escenario del día a día, escribir un código limpio y fácil de entender puede llevar más tiempo, pero a la larga, todo el equipo obtendrá muchos beneficios.
La implementación, el mantenimiento y la refactorización serán un desafío si trabajas con un código confuso o difícil de leer. Tú y tu equipo necesitarán pasar mucho tiempo para comprender lo que sucede allí, desperdiciando tiempo y esfuerzo.
¡Aprender código limpio es el mejor truco de productividad que cualquier desarrollador puede tener!
Vayamos a los detalles. ¿Te parece?
Características generales
Podemos considerar como características de Clean Code varios aspectos del desarrollo, tales como:
- Claridad: Clean Code es claro y fácil de entender. Utiliza nombres significativos para variables, funciones y clases y evita comentarios confusos o innecesarios.
- Simplicidad: es simple y directo. Evita la complejidad innecesaria y mantiene todo lo más sencillo posible.
- Modularidad: es modular y organizado. Se divide en pequeños módulos o funciones reutilizables, fáciles de probar y mantener.
- Consistencia: es consistente en su formato, nomenclatura y estilo de codificación. Esto facilita la lectura y reduce la probabilidad de errores.
- Testabilidad: está concebido para ser fácil de probar. Separa preocupaciones y dependencias y evita piezas de código que dependen mucho unas de otras, lo que es difícil de probar.
Pero ¿qué pasa con el frontend?
Si bien muchos de los principios de Clean Code son aplicables en cualquier lenguaje de programación, existen algunas consideraciones específicas que pueden ser útiles al desarrollar aplicaciones frontend.
A continuación veremos algunos casos de Clean Code, importantes para el frontend:
Separación de responsabilidad (Single Responsibility Principle)
Es importante que las diferentes responsabilidades de frontend estén separadas y organizadas de manera clara y coherente.
En este ejemplo, el componente UserProfile tiene una única responsabilidad: mostrar la información del perfil del usuario y proporcionar un botón de cierre de sesión. El componente toma el nombre, el correo electrónico y la avatarUrl como props y los usa para representar la información del perfil del usuario.
La función handleLogout también es definida dentro del componente. Esta función lidia con la lógica de logout del usuário cuando se hace clic en el botón. Al mantener esa lógica dentro del componente, seguimos el SRP (Single Responsibility Principle) y garantizando que cada componente tenga solo una responsabilidad.
Separar la lógica para mostrar la información del perfil de usuario y manejar la funcionalidad de logout en funciones separadas hace que este código sea más modular y fácil de mantener. Si necesitamos actualizar la lógica de logout, basta modificar la función handleLogout, lo cual no afecta el resto de la funcionalidad del componente. De la misma forma, si hace falta actualizar la información del perfil que se muestra, solo hay que modificar el código JSX sin afectar la funcionalidad de logout.
Nomenclatura
Las clases, los ID, los componentes y las funciones deben nombrarse de manera significativa y descriptiva para que el código sea más fácil de entender. Deben evitarse los nombres genéricos.
Aquí estamos usando buenos nombres, usando nombres descriptivos y significativos para nuestras variables y funciones. En lugar de usar nombres genéricos como name, usamos firstName y lastName para describir más específicamente el nombre de usuario.
Asimismo, usamos avatarUrl para describir la URL de la imagen del avatar del usuario, así como ${firstName}, avatar de ${lastName} para atributo alt de la imagen para describir qué es la imagen.
Usar nombres descriptivos hace el código más legible y fácil de entender. Cuando otros devs (o nosotros mismos) leemos el código después de un tiempo, podemos entender rápidamente qué hace cada variable o función, sin perder tiempo descifrando nombres.
Al usar una buena nomenclatura, también reducimos la probabilidad de errores y mejoramos la capacidad de mantenimiento del código. En caso de necesitar hacer cambios a futuro en el código, podremos entender sin problemas lo que hace cada parte del código y cambiar lo deseado.
Reutilización de código
En este ejemplo, usamos Clean Code para favorecer la reutilización de código. Tenemos separado el componente Button, lo que nos da la posibilidad de usarlo en otras partes de la aplicación, en vez de repetir el mismo código varias veces.
También reutilizamos este componente Button dentro del componente UserProfile, donde definimos la función handleLogout. Usando el componente Button con un label de Logout y un onClick de handleLogout, podemos crear un logout dentro de nuestro componente de perfil de usuario, sin tener que escribir el código del botón nuevamente.
Usando estos principios para mejorar la reutilización de código, reducimos la cantidad de código que debemos escribir, mejorar la capacidad de mantenimiento de nuestro código y disminuir la probabilidad de errores.
Testabilidad
Aquí puedes ver cómo volvemos más testable o sujeto a pruebas el componente UserProfile. El recurso principal de este ejemplo es la propiedad onLogout.
En lugar de definir la función handleLogout para lidiar directamente con la lógica de logout, usamos la propiedad onLogout para permitir que el componente patrón o padre defina la lógica de logout. También verificamos si la propiedad onLogout está definida antes de llamarla, para evitar errores en caso de no estar definida.
Eso nos permite probar fácilmente el componente UserProfile. De esa forma, podemos pasar una función simulada de onLogout durante la prueba, de modo de garantizar que sea llamada correctamente cuando se dé clic al botón Logout.
Aquí un ejemplo de prueba usando la librería Jest.js.
Mantenimiento
El código frontend de una aplicación puede volverse muy grande y complejo con el tiempo. Ese es uno de los motivos para usar Clean Code. De esa forma, tendremos un código limpio, fácil de mantener y poco tiempo invertido para entender cómo funcionan juntos todos los componentes. Seguramente, eso te ahorrará esfuerzos y recursos a largo plazo.
Ve este ejemplo:
Aquí específicamente estamos utilizando la desestructuración de objetos para simplificar el código y hacerlo más fácil de leer y modificar.
En lugar de pasar props individuales para el primer nombre, apellido, e-mail y URL del avatar del usuario, compartimos un objeto user único que contiene toda esa información. Eso vuelve el componente modular y fácil de modificar, pues nos permite agregar o remover propiedades del objeto user fácilmente, sin tener que modificar el código del componente.
Al usar Clean Code para mejorar la capacidad de mantenimiento de nuestro código, facilitamos la modificación y el cuidado a largo plazo.
Performance
Clean Code también mejora el desempeño del frontend, reduciendo la cantidad de código innecesario y optimizando el que sí se requiere. Lo anterior se traduce en tiempos de carga más rápidos y en una mejor experiencia del usuario.
Aquí muestro cómo mejorar el desempeño del componente UserList. Usamos el hook useMemo para memorizar la lista de usuarios clasificada, lo que reduce reprocesamientos innecesarios.
El hook useMemo recibe una función que devuelve un valor memorizado y un array de dependencias. Si cambia alguna de dichas dependencias, se recalcula el valor memorizado, pero si nunguna se modifica, el valor memorizado se obtiene del caché.
Esto puede ser particularmente útil en casos donde la base de usuarios es grande o la función de clasificación es costosa.
Como resultado de esa técnica de Clean Code utilizada, mejoramos el desempeño del código, con lo que podemos asegurar que la aplicación sea rápida y responsiva para los usuarios.
Accesibilidad
Clean Code también puede ayudar a mejorar la accesibilidad del frontend para usuarios con capacidades diferentes. Un código bien estructurado facilita la implementación de recursos de accesibilidad y garantiza que éstos funcionen correctamente.
Aquí añadimos una propiedad aria-label al botón, que ayuda a mejorar la accesibilidad para usuarios que dependen de tecnología asistida, como lectores de pantalla.
La propiedad aria-label ofrece una alternativa de texto para el botón, procesada por lectores de pantalla en lugar de texto visible. Esto resulta útil en los casos donde el texto visible del botón no es suficiente para transmitir la finalidad del botón a usuarios con capacidades diferentes.
Al sumar esa propiedad al componente Button, mejoramos la accesibilidad de nuestro código y garantizamos que pueda ser usado por la mayor cantidad posible de usuarios.
Consejos con Clean Code
Espero que a estas alturas hayas logrado entender qué es Clean Code, cómo usarlo y sus beneficios. Ahora, mostraré de forma más sucinta 7 consejos prácticos que son muy utilizados en el día a día de los desarrolladores frontend, y que consideramos como Clean Code:
1) Renderización condicional solo por una condición
Para renderizar algo condicionalmente cuando una condición fuera true y no renderizar nada cuando una condición fuera false, no uses un operador ternario. En vez de eso, usa el operador &&.
2) Renderización condicional en cualquiera de las condiciones
Si necesitas renderizar condicionalmente algo cuando una condición sea true y otro detalle cuando la condición sea false, usa un operador ternario.
3) Props Booleanas
Una propiedad truthy puede aplicarse a un componente solo con el nombre de la propredad sin un valor como éste: myTruthyProp. Escribir algo como myTruthyProp={true} es innecesario. Mira este ejemplo para entender mejor:
4) Props de string
Una props en el formato de string puede aplicarse entre comillas dobles sin usar llaves o backticks.
5) Funciones manipuladoras de eventos
Si un manipulador de eventos acepta solo un argumento para el objeto Event, puedes aplicar la función onChange={handleChange} al manipulador de eventos sin necesidad de agrupar la función en una anónima: onChange={e => handleChange(e)}.
6) Pasar componentes como Props
Al pasar un componente como una prop para otro componente, no hace falta envolverlo en una función si el componente no acepta ningún props.
7) Apoyos indefinidos
Las propiedades indefinidas son excluidas, entonces no te preocupes por proporcionar un undefined fallback si está bien que el prop sea undefined.
Estos son algunos de los principios de Clean Code que puedes aplicar tanto al desarrollo de aplicaciones frontend como backend. Recuerda estos principios:
- Es importante, al menos tan importante como otros conceptos como rendimiento y evitar bugs.
- Es fácil de leer para cualquier desarrollador.
- Es fácil de modificar para cualquier desarrollador.
- Fue escrito por alguien a quien le importa.
- Hace lo que se espera. El código no te engaña, sin sorpresas.
Como resultado, siempre tendremos un código más legible, más fácil de evolucionar, mantener y probar, generando un gran aumento en la productividad a largo plazo y, en consecuencia, desarrolladores más felices.
¡Espero que hayas disfrutado el artículo y estés emocionado/a de ponerlo todo en práctica!
¡Éxito!
Listopro Community da la bienvenida a todas las razas, etnias, nacionalidades, credos, géneros, orientaciones, puntos de vista e ideologías, siempre y cuando promuevan la diversidad, la equidad, la inclusión y el crecimiento profesional de los profesionales en tecnología.