Ir al contenido principal

Arquitectura Escalable con Clases en JavaScript

Arquitectura Escalable con Clases en JavaScript: De Código Spaghetti a Estructura Profesional

¿Tu proyecto JavaScript está creciendo y el código se vuelve inmanejable? Te presento el patrón ModeloBase que transformó mi código de spaghetti desorganizado a arquitectura limpia y escalable.

❌ El Caos del Código Duplicado

Antes tenía clases repetitivas para cada entidad de mi aplicación:

// ❌ Código duplicado para Producto
class Producto {
    constructor() {
        this.recurso = 'productos';
        this.server = this.getServer();
    }
    
    async lista(page = 1, filtro = '') {
        // 50 líneas de código repetitivo...
    }
    
    getServer() {
        return location.origin;
    }
}

// ❌ Mismo código duplicado para Cliente
class Cliente {
    constructor() {
        this.recurso = 'clientes';
        this.server = this.getServer();
    }
    
    async lista(page = 1, filtro = '') {
        // 50 líneas de código repetitivo... otra vez
    }
    
    getServer() {
        return location.origin;
    }
}
Problema: Duplicación de código, mantenimiento difícil, cambios tediosos y alta probabilidad de errores.

✅ La Solución: Patrón ModeloBase con Herencia

Creé una clase base reutilizable y clases específicas que la extienden:

// ✅ ModeloBase.js - Clase padre con funcionalidad común
export default class ModeloBase {
    constructor(recurso) {
        this.recurso = recurso;
        this.server = this.getServer();
        this.template = null;
    }

    setTemplate(template) {
        this.template = template;
    }

    getServer() {
        return location.origin;
    }

    async lista(page = 1, filtro = '') {
        // Lógica común para TODOS los modelos
        const url = `${this.server}/api/${this.recurso}?page=${page}&q=${filtro}`;
        const response = await fetch(url);
        const data = await response.json();
        
        // Usa el template específico de cada clase hija
        if (this.template) {
            return data.items.map(item => this.template(item)).join('');
        }
    }
}
// ✅ Producto.js - Clase específica y limpia
import ModeloBase from './ModeloBase.js';

export class Producto extends ModeloBase {
    constructor() {
        super('productos'); // ← Llama al constructor padre
        
        this.setTemplate(item => `
            <tr data-line_id="${item.producto}">
                <td>${item.producto}</td>
                <td>${item.descripcion}</td>
                <td>${item.unidadMedida}</td>
                <td>${item.precioUnitario}</td>
            </tr>
        `);
    }
    
    // ✅ Puedo agregar métodos ESPECÍFICOS de Producto
    calcularImpuestos(productoId) {
        // Lógica exclusiva de productos
    }
}
// ✅ Cliente.js - Otra clase específica
import ModeloBase from './ModeloBase.js';

export class Cliente extends ModeloBase {
    constructor() {
        super('clientes'); // ← Mismo padre, diferente recurso
        
        this.setTemplate(item => `
            <tr data-line_id="${item.cliente}">
                <td>${item.razonSocial}</td>
                <td>${item.ruc}</td>
                <td>${item.telefono}</td>
            </tr>
        `);
    }
    
    // ✅ Métodos específicos de Cliente
    obtenerHistorialCompras(clienteId) {
        // Lógica exclusiva de clientes
    }
}

🎯 Estructura de Herencia Visualizada

ModeloBase (Padre) Producto (Hijo) Cliente (Hijo)
recurso super('productos') super('clientes')
server ✅ Heredado ✅ Heredado
lista() ✅ Heredado ✅ Heredado
template 🔄 Específico 🔄 Específico
Métodos extra calcularImpuestos() obtenerHistorialCompras()

📈 Beneficios de Esta Arquitectura

✅ DRY Principle No te repitas - lógica común en un solo lugar
✅ Mantenibilidad Cambios en ModeloBase afectan a TODAS las clases hijas
✅ Escalabilidad Nuevas entidades en minutos: extends ModeloBase + super()
✅ Consistencia Todas las clases siguen la misma estructura
✅ Flexibilidad Cada clase hija puede especializarse según sus necesidades

🔧 Uso en la Práctica

// Inicialización limpia y consistente
const producto = new Producto();
const cliente = new Cliente();

// Mismo método, comportamiento diferente
producto.lista(1, 'laptop');    // → Busca en /api/productos
cliente.lista(1, 'empresa');    // → Busca en /api/clientes

// Métodos específicos de cada clase
producto.calcularImpuestos(123);
cliente.obtenerHistorialCompras(456);
💡 Patrón de Templates Integrado
Nota cómo cada clase define su propio template. Esto combina perfectamente con el patrón de herencia, permitiendo reutilizar la lógica de renderizado mientras personalizas la presentación.

🚀 Escalando tu Aplicación

¿Necesitas agregar una nueva entidad? Solo minutos:

// ✅ Proveedor.js - Nueva entidad en 2 minutos
import ModeloBase from './ModeloBase.js';

export class Proveedor extends ModeloBase {
    constructor() {
        super('proveedores'); // ← ¡Listo!
        
        this.setTemplate(item => `
            <tr>
                <td>${item.nombre}</td>
                <td>${item.contacto}</td>
            </tr>
        `);
    }
    
    // Agregar métodos específicos cuando los necesites
}
Conclusión
La herencia con clases en JavaScript no es solo teoría académica. Con el patrón ModeloBase, transformé mi código en una arquitectura profesional, mantenible y escalable. Ahora agregar nuevas funcionalidades es cuestión de minutos, no de horas.

Comentarios

Entradas populares de este blog

Instalación y Configuración de MySQL 5.7 en Ubuntu 24.04 LTS

Instalar MySQL 5.7 en Ubuntu 24.04 1. Descargar e instalar MySQL Copiar mkdir ~/mysql57 cd ~/mysql57 wget https://cdn.mysql.com/archives/mysql-5.7/mysql-5.7.44-linux-glibc2.12-x86_64.tar.gz tar -zxvf mysql-5.7.44-linux-glibc2.12-x86_64.tar.gz sudo mv mysql-5.7.44-linux-glibc2.12-x86_64 /usr/local/mysql sudo ln -s /usr/local/mysql/bin/mysql /usr/local/bin/mysql 2. Instalar dependencias necesarias IMPORTANTE: Se descargan las versiones nuevas de las librerías y se las vincula con las librerías que necesita MySQL. Copiar sudo apt update # Reemplazo de libaio sudo apt install libaio1t64 # Reemplazo de libtinfo y ncurses sudo apt install libtinfo6 libncurses6 Copiar # Crear los enlaces simbólicos sudo ln -sf /usr/lib/x86_64-linux-gnu/libaio.so.1t64 /usr/lib/libaio.so.1 sudo ln -sf /usr/lib/x86_64-linux-gnu/libtinfo.so.6 /usr/lib/x86_64-linux-gnu/libtinfo.so.5 sudo ln -sf /usr/lib/x86_64-linux-gnu/libncurses.so.6 /usr/lib/x86_64...

Instalar Evolution API en Docker con Redis y PostgreSQL Local

Instalar Evolution API en Docker con Redis y PostgreSQL Local En este tutorial vamos a levantar Evolution API usando Docker , con soporte de Redis para sesiones y PostgreSQL local para almacenar datos de manera persistente y compartida entre varios usuarios. 1. Estructura del proyecto Crea una carpeta para tu proyecto y colócate en ella: mkdir -p ~/docker/evolution-api cd ~/docker/evolution-api 2. Archivo docker-compose.yml Este compose levanta Redis y Evolution API : version: "3.9" services: # ✅ SERVICIO REDIS redis: container_name: evolution_redis image: redis:7-alpine restart: unless-stopped ports: - "6379:6379" volumes: - redis_data:/data command: redis-server --save 60 1 --loglevel warning # ✅ SERVICIO EVOLUTION API evolution-api: container_name: evolution_api image: atendai/evolution-api restart: unless-stopped ports: - "8085:8080" env_file: - .env ...

Instalar Jasper Studio 6.21 para Ubuntu 24.04

Instalar js-studiocomm_6.21.3 en Ubuntu 24.4 Para instalar Jaspersoft Studio en Ubuntu 24.4, sigue estos pasos: 1. Descargar Jasper Studio Descarga la versión js-studiocomm_6.21.3 desde el siguiente enlace: Jaspersoft Studio 6.21.3 2. Crear el directorio de instalación mkdir /opt/jasperstudio 3. Mover el archivo descargado mv /dir_descarga/js-studiocomm_6.21.3_linux_x86_64.tgz /opt/jasperstudio/ cd /opt/jasperstudio 4. Extraer el archivo tar -xvzf js-studiocomm_6.21.3_linux_x86_64.tgz cd js-studiocomm_6.21.3 5. Ejecutar Jaspersoft Studio ./Jaspersoft\ Studio 6. Crear acceso directo en el escritorio Para facilitar el acceso, crea un archivo .desktop en el escritorio: gedit ~/Escritorio/jaspersoft-studio.desktop En el archivo jaspersoft-studio.desktop , agrega lo siguiente: [Desktop Entry] Version=1.0 Ty...