Clean Code
La documentación sobre Clean Code se basa en una serie de principios y prácticas que ayudan a escribir código más legible, mantenible y escalable. El concepto fue popularizado por el libro “Clean Code” de Robert C. Martin, también conocido como “Uncle Bob”.
Principios Clave de Clean Code
Section titled “Principios Clave de Clean Code”1. Nombres Significativos
Section titled “1. Nombres Significativos”El código debe ser fácilmente comprensible por otros desarrolladores (o por ti mismo en el futuro). Los nombres de variables, funciones y clases deben describir claramente su propósito.
Mal ejemplo:
let d; // ¿Qué significa "d"?Buen ejemplo:
let userRegistrationDate; // El propósito es claro2. Funciones Pequeñas y Simples
Section titled “2. Funciones Pequeñas y Simples”Las funciones deben hacer una sola cosa y hacerlo bien. Si una función tiene múltiples responsabilidades, es más difícil de leer y mantener.
Mal ejemplo:
function processOrder(order) { validateOrder(order); chargeCreditCard(order); updateInventory(order); sendConfirmationEmail(order);}Buen ejemplo:
function processOrder(order) { validateOrder(order); charge(order); updateInventory(order); notifyCustomer(order);}
function charge(order) { chargeCreditCard(order);}
function notifyCustomer(order) { sendConfirmationEmail(order);}3. Evita Comentarios Innecesarios
Section titled “3. Evita Comentarios Innecesarios”El código debería explicarse por sí mismo. Si necesitas demasiados comentarios, el código puede estar mal escrito o los nombres de las funciones/variables no son lo suficientemente descriptivos.
Mal ejemplo:
// Verifica si el usuario está logueadoif (user.isLoggedIn()) { // Envía un email de confirmación sendEmail(user);}Buen ejemplo:
if (user.isLoggedIn()) { sendConfirmationEmail(user);}4. Evita Códigos Duplicados
Section titled “4. Evita Códigos Duplicados”El código duplicado hace que sea más difícil de mantener y actualizar. Utiliza funciones reutilizables.
Mal ejemplo:
function getUserFullName(user) { return user.firstName + " " + user.lastName;}
function getCustomerFullName(customer) { return customer.firstName + " " + customer.lastName;}Buen ejemplo:
function getFullName(person) { return person.firstName + " " + person.lastName;}5. Mantén los Métodos con Pocos Parámetros
Section titled “5. Mantén los Métodos con Pocos Parámetros”Las funciones con muchos parámetros son difíciles de leer y pueden generar errores. Intenta reducir el número de parámetros o agruparlos en objetos.
Mal ejemplo:
function createUser(firstName, lastName, email, age, address) { // Crear el usuario}Buen ejemplo:
function createUser(user) { // Crear el usuario}
let user = { firstName: "John", lastName: "Doe", email: "john.doe@example.com", age: 30, address: "123 Main St",};6. Usa Variables y Constantes en Lugar de Números Mágicos
Section titled “6. Usa Variables y Constantes en Lugar de Números Mágicos”Los números “mágicos” en el código son valores numéricos cuyo significado no es claro. Es mejor asignar esos valores a constantes con nombres descriptivos.
Mal ejemplo:
if (age > 65) { console.log("Senior");}Buen ejemplo:
const SENIOR_AGE = 65;if (age > SENIOR_AGE) { console.log("Senior");}7. No Reutilices Variables para Propósitos Diferentes
Section titled “7. No Reutilices Variables para Propósitos Diferentes”Reutilizar variables con propósitos diferentes puede confundir a quien lee el código.
Mal ejemplo:
let temp = 10; // temp se usa para la temperaturatemp = "John"; // ahora se usa para el nombre del usuarioBuen ejemplo:
let temperature = 10;let userName = "John";8. Usa Objetos en Lugar de Booleanos como Parámetros
Section titled “8. Usa Objetos en Lugar de Booleanos como Parámetros”Si una función necesita un parámetro booleano para controlar el flujo, es mejor pasar un objeto que contenga todos los valores relevantes.
Mal ejemplo:
function showUserProfile(isAdmin) { if (isAdmin) { // Mostrar perfil de admin } else { // Mostrar perfil de usuario }}Buen ejemplo:
function showUserProfile(user) { if (user.isAdmin) { // Mostrar perfil de admin } else { // Mostrar perfil de usuario }}9. Manejo Correcto de Errores
Section titled “9. Manejo Correcto de Errores”En lugar de capturar errores en todo el código, intenta manejarlos en los puntos específicos donde ocurren y con mensajes significativos.
Mal ejemplo:
try { // Mucho código aquí...} catch (error) { console.log("Something went wrong");}Buen ejemplo:
try { processPayment();} catch (error) { console.log("Error processing payment: " + error.message);}10. Sigue el Principio de Responsabilidad Única (SRP)
Section titled “10. Sigue el Principio de Responsabilidad Única (SRP)”Cada clase o módulo debe tener una única razón para cambiar. Es decir, debe ser responsable de una sola cosa.
Mal ejemplo:
class UserService { createUser() { // Lógica de creación de usuario }
sendWelcomeEmail() { // Lógica de enviar email de bienvenida }
logUserCreation() { // Lógica para registrar en logs }}Buen ejemplo:
class UserService { createUser() { // Lógica de creación de usuario }}
class EmailService { sendWelcomeEmail() { // Lógica de enviar email de bienvenida }}
class LogService { logUserCreation() { // Lógica para registrar en logs }}Diagrama de Flujo para Refactorización Clean Code
Section titled “Diagrama de Flujo para Refactorización Clean Code”Supongamos que tienes que refactorizar una función que se encarga de procesar una orden y tiene varias responsabilidades mezcladas. Aquí un diagrama de flujo para dividirlo en varias funciones:
- Identificar las responsabilidades: Procesar la orden, validar los datos, actualizar el inventario y enviar notificaciones.
- Crear funciones específicas para cada responsabilidad:
validateOrder(),chargeCustomer(),updateInventory(),sendConfirmationEmail(). - Encapsular en una función principal:
processOrder()llamará a cada una de estas funciones.
graph TD; A[processOrder] --> B[validateOrder] A --> C[chargeCustomer] A --> D[updateInventory] A --> E[sendConfirmationEmail]