Introducción:
En el mundo del diseño y desarrollo web, nos enfrentamos constantemente a la necesidad de aprender, aplicar y compartir conocimientos. Uno de los principios fundamentales que he aprendido en mi camino es el concepto de DRY, siglas en inglés de “Don’t Repeat Yourself”, que traducido al español significa “No te repitas a ti mismo”. Este principio busca promover un código limpio, eficiente y fácil de mantener, y hoy quiero explicarte detalladamente cómo aplicarlo en tus proyectos.

Contenido
¿Qué es DRY en programación?
El principio DRY tiene como objetivo evitar la repetición innecesaria de código dentro de un proyecto. Esto significa que cada fragmento de conocimiento o lógica debe estar representado en un solo lugar dentro del sistema. Cuando duplicamos código, nos exponemos a errores, dificultades de mantenimiento y problemas de escalabilidad en nuestras aplicaciones.
Este principio es especialmente relevante en proyectos grandes donde es común que, al trabajar rápidamente, se repitan funciones o lógicas similares en varios lugares.
¿Por qué es importante aplicar DRY?
Uno de los problemas más comunes que encontramos al desarrollar software es la duplicación de lógica. Veamos un ejemplo típico:
Ejemplo del formato de fechas:
Supongamos que creaste una función para dar formato a las fechas en tu aplicación. Sin aplicar DRY, podrías terminar copiando esa lógica directamente en diferentes partes del proyecto. Si luego necesitas cambiar el formato, tendrías que modificar manualmente cada instancia donde se repita la función. Esto puede ser manejable si ocurre en dos lugares, pero ¿y si está en 20 o 30? El tiempo que tomaría actualizar todo sería considerable, además de aumentar el riesgo de cometer errores.
Aplicando DRY, esa función se escribiría una sola vez y sería llamada desde cualquier lugar donde se necesite. Si decides cambiar el formato de fecha en el futuro, solo tendrías que modificar el código en un único lugar, ahorrando tiempo y esfuerzo.
Cómo aplicar DRY en tus proyectos
Para implementar el principio DRY de manera efectiva, aquí tienes algunas estrategias prácticas:
- Planificación previa:
Antes de escribir código, piensa en la lógica general que necesitarás. Si estás creando, por ejemplo, endpoints para una REST API, analiza si hay tareas o procesos que se repiten. Esto te ayudará a identificar partes del código que pueden abstraerse en funciones reutilizables. - Crear funciones reutilizables:
A medida que desarrolles, observa si existe lógica repetida entre diferentes módulos o funciones. Si encuentras duplicación, considera mover esa lógica a una función que pueda ser llamada desde distintos lugares. - Servicios generales:
Si identificas que una funcionalidad será utilizada por múltiples módulos, como el envío de correos electrónicos o la validación de datos, considera crear un servicio general. Por ejemplo, un servicio de envío de emails podría recibir parámetros como destinatario, asunto y cuerpo del mensaje, centralizando así la lógica de envío y haciendo tu código más limpio.
Ejemplo práctico de DRY en acción
En mi proyecto personal Marbust Accounts, he aplicado DRY en varias áreas clave. Aquí te comparto dos ejemplos:
En controladores:
Para generar códigos OTP (One-Time Password), tengo una única función dentro del controlador de cuentas. De esta forma, cualquier endpoint que necesite generar un OTP simplemente llama a esta función. Si en el futuro decido cambiar el número de dígitos del código, solo debo modificarlo en un lugar.
Función de Generar OTP:
const generateOtpCode = () => {
return Math.floor(100000 + Math.random() * 900000).toString();
};Llamando Función desde otro endpoint:
exports.register = async (req, res) => {
try {
const { firstName, lastName, email, phone, password } = req.body;
const otpCode = generateOtpCode();
...
...
}
};Como servicio general:
El envío de correos electrónicos es una funcionalidad recurrente en muchas aplicaciones. En lugar de replicar la lógica de envío en diferentes controladores, creé un servicio dedicado. Este servicio recibe parámetros como destinatario, asunto y contenido, y se encarga de realizar la configuración y el envío del correo. Así, cualquier módulo que necesite enviar un email puede utilizar este servicio de manera uniforme.
Creando Servicio:
const nodemailer = require('nodemailer');
const config = require('../config');
const transporter = nodemailer.createTransport({
host: config.nodemailer.host,
port: config.nodemailer.port,
secure: config.nodemailer.secure,
auth: {
user: config.nodemailer.user,
pass: config.nodemailer.password
},
connectionTimeout: 10000,
greetingTimeout: 10000,
socketTimeout: 10000
});
const sendEmail = async (emailTo, emailSubject, emailBody) => {
try {
const mailOptions = {
from: config.nodemailer.user,
to: emailTo,
subject: `${emailSubject} | ${config.appName} System`,
html: `
<h1 style='text-align: center;'>${emailSubject}</h1>
<hr />
${emailBody}
<hr />
<p style='text-align: center;'><strong>${config.appName}®</strong> System </br>© ${new Date().getFullYear()} <a href="https://marbust.com" style="font-weight: bold;">Marbust Technology Company</a> - All Rights Reserved</p>
`
};
const info = await transporter.sendMail(mailOptions);
console.log(`Email was sent to: ${emailTo} with Id: ${info.response}`);
} catch (error) {
console.log(error);
}
}
module.exports = sendEmail;Llamada y uso desde un Controlador:
// Llamada:
const sendEmail = require('../services/sendEmail.service');
// Uso
exports.login = async (req, res) => {
try {
...
...
const emailSubject = 'Notificación de inicio de sesión';
const emailBody = `Tu cuenta ha iniciado sesión el <strong>${new Date().toLocaleString()}</strong> desde la dirección IP <strong>${req.ip}</strong>`;
await sendEmail(email, emailSubject, emailBody);
...
...
};Beneficios de aplicar DRY
- Facilita el mantenimiento: Al tener la lógica centralizada, es más sencillo realizar cambios o correcciones.
- Reduce errores: Menos duplicación significa menos riesgo de inconsistencias.
- Aumenta la escalabilidad: Facilita la adición de nuevas funcionalidades sin complicar el código existente.
- Mejora la legibilidad: Un código organizado y sin repeticiones es más fácil de entender y trabajar para otros desarrolladores.
Conclusión
Aunque puede ser tentador escribir código rápido para cumplir con plazos ajustados, es importante recordar que el esfuerzo inicial de aplicar DRY vale la pena a largo plazo. Un código limpio, organizado y reutilizable es esencial para desarrollar aplicaciones que sean fáciles de mantener y escalar.
Te animo a que apliques este principio en tus proyectos y veas cómo mejora tu flujo de trabajo. Si deseas aprender más sobre diseño y desarrollo web, te invito a explorar otros artículos en mi blog, donde comparto consejos, herramientas y mejores prácticas. ¡Nunca dejes de aprender y compartir!
Sobre el Autor:

Marco Antonio Bustillos Quiroz
Bachelor of Science in Web Design and Development (BYU-Idaho)
Full Stack Web Developer con más de 7 años de experiencia en desarrollo Front End y 5 años en desarrollo Back End. Mis proyectos incluyen sitios web, landing pages, aplicaciones web, REST APIs, e-commerce, y mucho más. Mi pasión es crear experiencias digitales impactantes y compartir conocimientos con otros desarrolladores.