5-4-MVC
¡Excelente! Aquí tienes la versión MVC sin rutas separadas, manteniendo la misma simplicidad pero organizado en modelo, vista y controlador, todo integrado desde app.js.
📁 Estructura del proyecto (sin carpeta routes)
mvc-sin-routes/
├── app.js
├── models/
│ └── productoModel.js
├── views/
│ └── productoView.js
└── controllers/
└── productoController.js1. Modelo (models/productoModel.js)
// Base de datos en memoria
let productos = [
{ id: 1, nombre: 'Laptop', precio: 1000 },
{ id: 2, nombre: 'Mouse', precio: 25 },
{ id: 3, nombre: 'Teclado', precio: 50 }
];
// Obtener todos
const getAll = () => productos;
// Obtener por ID
const getById = (id) => productos.find(p => p.id === id);
// Crear nuevo producto
const create = (nombre, precio) => {
const nuevoId = productos.length > 0 ? Math.max(...productos.map(p => p.id)) + 1 : 1;
const nuevoProducto = { id: nuevoId, nombre, precio: parseFloat(precio) };
productos.push(nuevoProducto);
return nuevoProducto;
};
module.exports = { getAll, getById, create };2. Vista (views/productoView.js)
// Vista: listado completo + formulario
const listadoView = (productos) => {
let listaItems = '';
for (let p of productos) {
listaItems += `
<li>
<strong>${p.nombre}</strong> - $${p.precio}
(<a href="/productos/${p.id}">Ver detalles</a>)
</li>
`;
}
return `
<!DOCTYPE html>
<html>
<head>
<title>Productos</title>
<style>body { font-family: Arial; margin: 30px; } li { margin: 10px 0; }</style>
</head>
<body>
<h1>📦 Lista de productos</h1>
<ul>${listaItems}</ul>
<hr>
<h2>➕ Agregar producto</h2>
<form action="/productos" method="POST">
<input type="text" name="nombre" placeholder="Nombre" required>
<input type="number" step="1" name="precio" placeholder="Precio" required>
<button type="submit">Crear</button>
</form>
</body>
</html>
`;
};
// Vista: detalle de un producto
const detalleView = (producto) => `
<!DOCTYPE html>
<html>
<head>
<title>${producto.nombre}</title>
<style>body { font-family: Arial; margin: 30px; }</style>
</head>
<body>
<h1>📄 Detalle del producto</h1>
<p><strong>ID:</strong> ${producto.id}</p>
<p><strong>Nombre:</strong> ${producto.nombre}</p>
<p><strong>Precio:</strong> $${producto.precio}</p>
<a href="/">← Volver al listado</a>
</body>
</html>
`;
// Vista: error 404
const error404View = () => `
<!DOCTYPE html>
<html>
<head><title>Error 404</title></head>
<body>
<h1>404 - Producto no encontrado</h1>
<a href="/">Volver</a>
</body>
</html>
`;
// Vista: error por datos faltantes
const errorDatosView = () => `
<!DOCTYPE html>
<html>
<head><title>Error</title></head>
<body>
<h1>Error: faltan nombre o precio</h1>
<a href="/">Volver</a>
</body>
</html>
`;
module.exports = { listadoView, detalleView, error404View, errorDatosView };3. Controlador (controllers/productoController.js)
const model = require('../models/productoModel');
const view = require('../views/productoView');
// GET / - Mostrar todos los productos
const listar = (req, res) => {
const productos = model.getAll();
res.send(view.listadoView(productos));
};
// GET /productos/:id - Mostrar detalle
const mostrarDetalle = (req, res) => {
const id = parseInt(req.params.id);
const producto = model.getById(id);
if (!producto) {
return res.status(404).send(view.error404View());
}
res.send(view.detalleView(producto));
};
// POST /productos - Crear producto
const crear = (req, res) => {
const { nombre, precio } = req.body;
if (!nombre || !precio) {
return res.status(400).send(view.errorDatosView());
}
model.create(nombre, precio);
res.redirect('/');
};
module.exports = { listar, mostrarDetalle, crear };4. Aplicación principal (app.js) - sin archivo de rutas
const express = require('express');
const app = express();
const PORT = 3000;
// Importar el controlador (ya tiene la lógica)
const controller = require('./controllers/productoController');
// Middleware para leer formularios
app.use(express.urlencoded({ extended: true }));
// ---------- RUTAS DEFINIDAS DIRECTAMENTE ----------
app.get('/', controller.listar);
app.get('/productos/:id', controller.mostrarDetalle);
app.post('/productos', controller.crear);
// Iniciar servidor
app.listen(PORT, () => {
console.log(`✅ Servidor MVC (sin routes) en http://localhost:${PORT}`);
});▶️ Cómo ejecutar
Crear la estructura de carpetas y archivos.
Instalar Express:
npm init -y npm install expressEjecutar:
node app.jsAbrir
http://localhost:3000y probar.
✅ ¿Qué aprenden con esta versión?
Patrón MVC sin la complejidad adicional de un enrutador separado.
Separación de responsabilidades en modelos, vistas y controladores.
Las rutas están en
app.jspero el controlador maneja la lógica.Fácil de entender para alumnos que dan sus primeros pasos en arquitectura MVC.
Es exactamente igual en funcionalidad al ejercicio original, pero con el código organizado en capas. ¡Perfecto para enseñar MVC de forma gradual
Comentarios
Publicar un comentario