Por qué la arquitectura no se trata de diagramas aburridos
Imagina que estás construyendo una casa. Puedes simplemente apilar ladrillos, verter hormigón y esperar que la estructura no se derrumbe. O puedes diseñar los cimientos, los muros de carga y los techos. En el desarrollo con JavaScript es lo mismo: sin una arquitectura bien pensada, tu proyecto se convierte en "código espagueti", donde modificar una función rompe toda la aplicación.
Los patrones arquitectónicos no son teoría seca de libros. Son esquemas de batalla probados que te ayudarán a:
- No volverte loco cuando el proyecto crezca hasta 50,000 líneas de código.
- Encontrar errores rápidamente, porque el código está dividido en bloques lógicos.
- Añadir funcionalidades sin miedo a romper algo.
En este artículo analizaremos cinco patrones clave para aplicaciones JavaScript: desde el clásico MVC hasta el enfoque modular. ¡Allá vamos!
MVC (Model-View-Controller): el abuelo de todos los patrones
MVC es el estándar de oro del desarrollo web. El patrón divide la aplicación en tres capas:
- Model — datos y lógica de negocio (CRUD, validación).
- View — la interfaz que ve el usuario (HTML, renderizado).
- Controller — el intermediario: recibe las solicitudes del usuario y actualiza el Model o la View.
Así es como se ve en el código:
// Modelclass UserModel { constructor() { this.users = []; }
addUser(user) { this.users.push(user); }
getUsers() { return this.users; }}
// Viewclass UserView { render(users) { const list = document.getElementById('user-list'); list.innerHTML = users.map(u => `<li>${u.name}</li>`).join(''); }}
// Controllerclass UserController { constructor(model, view) { this.model = model; this.view = view; }
addUser(name) { this.model.addUser({ name, id: Date.now() }); this.view.render(this.model.getUsers()); }}
// Usoconst model = new UserModel();const view = new UserView();const controller = new UserController(model, view);controller.addUser('Alicia');controller.addUser('Bob');¿Cuándo usar MVC en JavaScript? Ideal para SPA (aplicaciones de una sola página) medianas y grandes. Pero ten cuidado: si la View depende mucho del Model, el patrón se convierte en "Massive View Controller" — el controlador se infla de manera exagerada.
MVP (Model-View-Presenter): el supervisor estricto
MVP es una evolución de MVC, donde el Presenter asume toda la lógica de control de la View. A diferencia de MVC, la View en MVP es una capa pasiva y "tonta". Solo muestra datos y transmite eventos al Presenter.
// Model (el mismo que en MVC)class UserModel { constructor() { this.users = []; } addUser(user) { this.users.push(user); } getUsers() { return this.users; }}
// View — interfaz pasivaclass UserView { constructor() { this.list = document.getElementById('user-list'); this.addButton = document.getElementById('add-btn'); }
bindAddUser(handler) { this.addButton.addEventListener('click', () => { const name = prompt('Ingrese el nombre:'); if (name) handler(name); }); }
render(users) { this.list.innerHTML = users.map(u => `<li>${u.name}</li>`).join(''); }}
// Presenter — el cerebro de la aplicaciónclass UserPresenter { constructor(model, view) { this.model = model; this.view = view; this.view.bindAddUser(this.handleAddUser.bind(this)); this.view.render(this.model.getUsers()); }
handleAddUser(name) { this.model.addUser({ name, id: Date.now() }); this.view.render(this.model.getUsers());