Te doy la bienvenida a esta segunda parte del tutorial, en ella veremos los dos últimos conceptos que me quedaron sin explicar y veremos las distintas capas a la hora de organizar el código con DDD.
Si te perdiste el primer tutorial, aquí tienes el enlace para que puedas seguirlo :)
En Domain-Driven Design (DDD), los Contextos Acotados (Bounded Contexts) son una forma de dividir un sistema grande en partes más pequeñas y manejables. Cada contexto tiene su propio modelo de dominio, sus propias reglas de negocio y su propia terminología.
Piensa en un Contexto Acotado como una "zona independiente" dentro de una aplicación, donde los términos y reglas tienen un significado específico.
🛒 Ejemplo: Tienda Online
Siguiendo nuestro ejemplo de tienda en línea. Tu aplicación puede tener varios módulos o contextos acotados, como:
1️⃣ Catálogo de Productos 🏷️
Maneja los productos, precios y descripciones.
Contiene el Producto con atributos como nombre, precio y stock.
2️⃣ Carrito de Compras 🛍️
Se encarga de añadir productos al carrito y calcular el total.
Contiene ProductoDelCarrito, que guarda productos con la cantidad seleccionada.
3️⃣ Pedidos y Pagos 💳
Procesa órdenes y pagos.
Contiene Pedido y Pagos, con estados de pago.
4️⃣ Usuarios y Autenticación 👤
Gestiona clientes, direcciones y métodos de pago.
Contiene User, con sus atributos.
Cada contexto acotado tiene sus propias entidades, servicios y repositorios, y aunque pueden compartir información, se comunican entre sí de forma controlada.
🎯 Ejemplo de Separación de Contextos
Si tenemos un producto en el Catálogo de Productos, su estructura puede verse así:
Probablemente, hayas escuchado hablar de DDD (Domain-Driven Design) en varias ocasiones e incluso leído algún artículo o realizado algún curso, pero aún no lo entiendes del todo y no te atreves a aplicarlo en un proyecto.
No te preocupes, a mí me pasó lo mismo. La mayoría de los recursos disponibles están llenos de teoría y términos que, en lugar de aclarar, generan más confusión.
Además, muchos carecen de ejemplos prácticos o presentan estructuras tan diferentes entre sí que terminan desorientándonos. También existen cursos con un nivel de complejidad innecesario, donde se añaden detalles que poco tienen que ver con DDD, haciéndonos perder de vista lo realmente importante: aprender a usarla.
En cuanto a las estructuras, no te preocupes. Mientras sigamos las capas fundamentales, podemos permitirnos cierta flexibilidad dentro de ellas. Una vez comprendas bien estas capas, serás capaz de interpretar y trabajar en cualquier proyecto basado en DDD.
¿Qué es DDD? 🤔
Significa (Domain-Driven Design, o Diseño Guiado por el Dominio). Y como su nombre indica, es el desarrollo de nuestra aplicación guiado por el dominio.
Pero, ¿Qué quiere decir realmente esto?
Imagina que quieres construir una web para una tienda en línea. Hay muchas partes en el sistema: los productos, los clientes, los pedidos, los pagos, etc. DDD es una forma de organizar y estructurar tu código para que se enfoque en cómo funciona el negocio en la vida real.
En lugar de empezar pensando en la base de datos o en las pantallas de usuario, como hacemos normalmente, DDD primero se centra en entender el negocio y reflejarlo en el código de manera clara y organizada.
🔑 Conceptos básicos de DDD
📌 1. El Dominio (Domain)
El "Dominio" es simplemente el problema o área de conocimiento que estás resolviendo con tu aplicación.
Ejemplo: Imagínate que eres freelance y uno de tus clientes quiere que le crees una web para una tienda online, el dominio es la "venta de productos en línea".
📌 2. Modelo del Dominio (Domain Model)
El modelo del negocio es el conjunto de reglas y lógica que describen cómo funciona el negocio. En nuestro ejemplo de tienda online, el código trata de representar cómo nuestro cliente, describe su trabajo.
Ejemplo:
Un cliente puede hacer un pedido.
Un pedido tiene una lista de productos y un precio total.
Un producto tiene un stock, y si se agota, no se puede comprar.
En Domain-Driven Design (DDD), el modelo de dominio representa la lógica central de negocio con clases puras, sin depender de infraestructura (como bases de datos o frameworks).
Las clases del modelo de dominio deben: ✔ Representar conceptos del negocio.
✔ No depender de un Framework, bases de datos, ni controladores.
✔ Encapsular la lógica y reglas de negocio.
📌 ¿Por qué separar el dominio?
✅ Facilita cambios sin romper toda la aplicación. ✅ Puedes probar la lógica del negocio sin depender de la base de datos. Como veremos más adelante, esto nos va a ayudar enormemente a la hora de hacer tests. ✅ Evita que un framework u ORM controlen tu modelo de negocio.
📌 3. Lenguaje Ubicuo (Ubiquitous Language)
Es un lenguaje común entre los desarrolladores y expertos del negocio (en este caso, nosotros y nuestro cliente) para que todos hablen el mismo idioma.
Ejemplo: En vez de usar nombres técnicos como Tbl_Orders, en DDD, diríamos Pedido, porque así lo llaman los dueños del negocio.
Esto hace que el código sea fácil de entender tanto para programadores como para personas no técnicas.
Si quieres mantener un estilo en inglés en todo el código, que es lo que yo te recomiendo, pero tu cliente usa términos en español, lo ideal es definir un Glosario del Lenguaje Ubicuo donde:
✅ Se documenten los términos clave en español e inglés. ✅ Se acuerde un conjunto de términos en inglés que todos (tú y el cliente) usarán. ✅ Se mantenga la coherencia en nombres de clases, métodos, variables y tablas.
📌 Ejemplo: Tienda Online (Español → Inglés)
Supongamos que tu cliente usa términos en español:
Pedido → Order
Cliente → Customer
Producto → Product
Carrito de compras → ShoppingCart
📌 Glosario documentado para el equipo
Español
Inglés
Pedido
Order
Cliente
Customer
Producto
Product
Carrito de compras
ShoppingCart
🎯 ¿Cómo asegurarnos de mantener el lenguaje consistente?
✅ Documentar el glosario y compartirlo con el equipo. ✅ Usar siempre inglés en el código (clases, métodos, variables, base de datos). ✅ Comunicar el mapeo al cliente, explicando que en código usamos inglés, pero sigue representando su negocio. ✅ Evitar mezclar idiomas (ejemplo incorrecto: PedidoService en vez de OrderService).
📌 4. Entidades y Objetos de Valor
DDD divide los datos en dos tipos principales:
Entidades: Tienen un identificador único y pueden cambiar con el tiempo. Ejemplo: Un Producto con un ID y un stock que va a cambiar.
Objetos de Valor (Value Objects): No tienen identidad propia y son inmutables. Ejemplo: Stock de un producto, podemos crear un value object para el stock en que podremos añadir las validaciones necesarias como que no acepte un número negativo. No te preocupes si no lo entiendes porque lo vamos a ver a fondo cuando nos metamos con el código.
📌 5. Agregados (Aggregates)
Son grupos de objetos que deben mantenerse juntos como una unidad.
Ejemplo: Un Pedido tiene que tener siempre Productos y un pedido sin ningún producto no tiene sentido de existencia. No podemos modificar un Producto dentro de un Pedido sin afectar al Pedido completo.
El Pedido sería el Agregado, y los Productos serían parte de él.
📌 6. Repositorios (Repositories)
Son las "puertas de entrada" para acceder y almacenar información en la base de datos sin que los objetos del dominio se preocupen por los detalles técnicos, siguiendo el principio de responsabilidad única de SOLID.
Por ejemplo, en lugar de que un Pedido acceda directamente a una base de datos, usamos una clase PedidoRepositorio que maneja la lógica de guardar pedidos, actualizarlos, borrarlos, listarlos o recuperar uno por su identificador.
Entonces solo necesitamos poder convertir los valores de nuestro dominio a una entidad como puede ser de Doctrine y desde PedidoRepositorio manejaremos el tratamiento de los datos como una inserción, actualización, listado de datos, etc.
En el dominio, crearemos una interfaz PedidoRepositorioInterface para definir que acciones podrá realizar PedidoRepositorio.
📌 7. Servicios de Dominio (Domain Services)
A veces, una operación no pertenece a una sola entidad, sino que afecta a varias. Para esos casos usamos Servicios de Dominio.
Un ejemplo de regla de negocio sería que un Cliente no pudiera realizar un pedido de un producto sobre más stock del que tenemos de un producto. En este caso no pertenece solo al Pedido y al Producto, sino a los dos.
Fin de la primera parte
Como se está haciendo muy larga esta parte teórica, lo he dividido en dos partes. Puedes continuar la siguiente parte de este tutorial desde el siguiente enlace:
En esta segunda parte del tutorial, vamos a meternos de lleno en la creación de los componentes para poder escribir y recuperar los comentarios con Svelte 5 y SvelteKit.
Antes de empezar 🛑 y como siempre, si te has perdido alguno de los tutoriales de esta serie, aquí te dejo todos los tutoriales escritos hasta ahora:
Parte 2: Crear comentarios en nuestro blog de Svelte 5 y Sveltkit y optimizaciones 🚩
Modificación de las funciones de posts para recuperar su identificador
Ya que necesitaremos el identificador de un post para poder crear un comentario, abrimos el archivo src\lib\server\db\db-posts.ts y añadimos las siguientes modificaciones para recuperar también el ID del post:
import { eq, and, type InferSelectModel, desc } from 'drizzle-orm';
En esta primera parte del tutorial vamos a añadir unas mejoras para tener un código más limpio y organizado y además crearemos nuevos componentes y funciones que usaremos en la segunda parte de este tutorial para trabajar con los comentarios.
Antes de empezar 🛑 y como siempre, si te has perdido alguno de los tutoriales de esta serie, aquí te dejo todos los tutoriales escritos hasta ahora:
Antes de continuar con los comentarios, vamos a renombrar la carpeta src\routes\api\blog a src\routes\api\posts para que el nombre sea más coherente. Realizamos este cambio porque, siguiendo las convenciones, las rutas suelen nombrarse en plural para reflejar colecciones de datos. Además, considero que "posts" describe mejor el propósito de esta ruta que "blog".
Recuerda que también deberás editar la petición a la API que realizamos en src\routes\+page.svelte para que apunte a nueva ruta.
Archivo para Gestionar Comentarios
Siguiendo el mismo enfoque que utilizamos para gestionar los posts y los usuarios, crearemos un archivo dedicado para manejar las operaciones relacionadas con los comentarios. Este archivo se llamará src\lib\server\db\db-comments.ts y contendrá todas las funciones necesarias para interactuar con la tabla de comentarios.
Una vez que hayas creado el archivo, añade el siguiente contenido:
import { desc, eq, type InferSelectModel } from "drizzle-orm";
En este tutorial, veremos cómo crear una página de registro utilizando Svelte 5 y SvelteKit. Crearemos el formulario y lo enviaremos a nuestro servidor donde validaremos la información recibida y crearemos el usuario.
Antes de empezar 🛑 y como siempre, si te has perdido alguno de los tutoriales de esta serie, aquí te dejo todos los tutoriales escritos hasta ahora:
Página de registro de nuestro blog con Svelte 5 y SvelteKit 🚩
Siguiente parte en construcción 👷
Mover los estilos de los formularios en login a app.css
Dado que los estilos utilizados en el registro serán los mismos que en el login, vamos a centralizarlos para facilitar el mantenimiento. Para ello, moveremos los estilos de src/routes/login/+page.svelte al archivo global src/app.css. Además, crearemos una clase específica llamada form-auth para sustituir a la clase form. Esto nos permitirá evitar colisiones en caso de que necesitemos crear otros formularios con formatos diferentes.
Abrimos el archivo src/app.css y añadimos el siguiente contenido:
👋 Soy Alberto, Back-end Developer con más de 12 años de experiencia en PHP, Python y TypeScript, aunque también disfruto del desarrollo Front-end. He realizado proyectos con Svelte y actualmente estoy aprendiendo React y Next.js.
Utilizamos cookies propias y de terceros para recopilar y analizar datos sobre la interacción de los usuarios con cosasdedevs.com.
Ver política de cookies.