Skip to content

Commit

Permalink
Merge pull request #107 from ucudal/feature/ddd
Browse files Browse the repository at this point in the history
Added more references to DDD
  • Loading branch information
fmachadopiriz authored Nov 3, 2024
2 parents 4b164a5 + 46d5f76 commit 5d1c17d
Show file tree
Hide file tree
Showing 12 changed files with 210 additions and 99 deletions.
58 changes: 39 additions & 19 deletions 4_Conceptos/4_Agregado.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,36 @@

## Agregado

Este documento está basado en [^1].
Este documento está basado en [^2] y [^1].

[^2]: Evans, E. (2015). Domain-Driven Design Reference: Definitions and Pattern
  Summaries. Domain Language, Inc. Disponible
  [aquí](https://www.domainlanguage.com/wp-content/uploads/2016/05/DDD_Reference_2015-03.pdf).

[^1]: Avram, A; Marinescu, F. (2006). Domain-Driven Design Quickly. InfoQ.
Disponible
[aquí](https://www.infoq.com/minibooks/domain-driven-design-quickly/).

Un modelo puede contener una gran cantidad de objetos del
[dominio](./4_Dominio.md), lo que implica una gran cantidad de asociaciones,
creando una complicada red de relaciones. El desafío principal de realizar un
buen modelo va de la mano de esta idea, y es que la labor más complicada no es
que el modelo sea completo, sino que el modelo sea lo suficientemente simple y
entendible. Una técnica para simplificar un modelo es la de utilizar agregados.

Un agregado es un grupo de objetos asociados que son considerados como una
unidad a la hora de realizar cambios en los datos. Cada agregado está compuesto
por una [entidad](./4_Entidad.md) que es denominada la **raíz** del agregado, y
esta es el único objeto del agregado que es accesible desde el exterior —esto
es, por objetos que no forman parte del agregado—.

La raíz puede mantener referencias a cualquiera de los objetos del agregado, y
los otros objetos del agregado pueden mantener referencias entre ellos, pero un
objeto no perteneciente al agregado solo puede mantener referencias a la raíz
del agregado. En caso de que haya otras entidades dentro del agregado, la
identidad de estas entidades es local al agregado.
[dominio](./4_Dominio.md) y una gran cantidad de asociaciones entre estos
objetos, creando una complicada red de referencias entre ellos. El desafío
principal de realizar un buen modelo va de la mano de esta idea, y es que la
labor más complicada no es que el modelo sea completo, sino que el modelo sea lo
suficientemente simple y entendible.

En el contexto de *Domain-Driven Design* —DDD, por sus siglas—, una técnica para
simplificar un modelo es la de utilizar agregados.

Un agregado es un grupo de objetos asociados —[entidades](./4_Entidad.md) y
[objetos valor](./4_Objeto_Valor.md)— que son considerados como una unidad a la
hora de realizar cambios en los datos.

Una de las entidades es denominada la **raíz** del agregado. La raíz puede
mantener referencias a cualquiera de los objetos del agregado, y los otros
objetos del agregado pueden mantener referencias entre ellos, pero un objeto no
perteneciente al agregado solo puede mantener referencias a la raíz del
agregado. En caso de que haya otras entidades dentro del agregado, la identidad
de estas entidades es local al agregado.

Al evitar que objetos externos tengan referencias a objetos internos del
agregado, se asegura la integridad de los datos del agregado, ya que los objetos
Expand All @@ -35,9 +41,23 @@ interno, lo cual permite que esta operación sea controlable. Al mismo tiempo, s
el objeto raíz es eliminado, el resto de objetos del agregado serán eliminados
también, ya que no hay ningún otro objeto que mantenga una referencia a ellos.

El uso de agregados permite establecer mejores límites para las transacciones y
para la distribución de los datos persistidos de los objetos:

* Dentro del agregado, las actualizaciones son sincrónicas y la consistencia,
que es fuerte, se logra usando transacciones.

* Fuera del agregado, las actualizaciones son asíncronas y la consistencia es
eventual.

* Los datos del agregado se mantienen dentro del mismo nodo en el que reside el
cómputo que gestiona el agregado, por ejemplo, su [repositorio](./4_Repository.md).

* Los datos de diferentes agregados pueden estar en nodos diferentes.

Para implementar un agregado, puedes seguir los siguientes pasos:

* Agrupa las entidades y los [objetos valor](./4_Objeto_Valor.md) en agregados.
* Agrupa las entidades y los objetos valor en agregados.

* Elije una entidad del agregado para que sea su raíz y controla todos los
accesos a los objetos internos del agregado a través de la raíz.
Expand Down
20 changes: 14 additions & 6 deletions 4_Conceptos/4_Dominio.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,32 @@

## Dominio

Este documento está basado en [^1].
Este documento está basado en [^2] y [^1].

[^2]: Evans, E. (2015). Domain-Driven Design Reference: Definitions and Pattern
  Summaries. Domain Language, Inc. Disponible
  [aquí](https://www.domainlanguage.com/wp-content/uploads/2016/05/DDD_Reference_2015-03.pdf).

[^1]: Avram, A; Marinescu, F. (2006). Domain-Driven Design Quickly. InfoQ.
Disponible
[aquí](https://www.infoq.com/minibooks/domain-driven-design-quickly/).

El dominio es un área de conocimiento, influencia o actividad. El área temática
a la que el usuario aplica un programa es el dominio del software. Compáralo
con [trabajo o área de trabajo](./4_Trabajo_y_area_de_trabajo.md).

En el contexto de *Domain-Driven Design* —DDD, por sus siglas—, dominio refiere
al contexto en el cual encaja el sistema, y es el aspecto central de esta
filosofía. En DDD, el dominio es el lugar en el cual se debe empezar el proceso
de modelado; todo software pertenece a un dominio, y es complicado crear
software que cubra una necesidad en un dominio si no se tiene suficiente
conocimiento sobre este último.

El software está relacionado con el dominio, entonces debe incluir los conceptos
fundamentales pertenecientes al dominio y ser un reflejo de él, de forma que
pueda encajar armónicamente en el dominio y mejorarlo.
El software está relacionado con el dominio, por lo tanto, debe incluir los
conceptos fundamentales pertenecientes al dominio y ser un reflejo de éste, de
forma que pueda encajar armónicamente en el dominio y mejorarlo.

Para bajar el dominio a tierra, primero se crea una abstracción del mismo, la
cual puede ser creada solo luego de haber hablado con los expertos del dominio,
Para bajar el dominio a tierra, primero se crea una abstracción de éste, la
que puede ser creada solo luego de haber hablado con los expertos del dominio,
esto es, esas personas que forman parte de él, trabajan en él, o simplemente lo
conocen a profundidad.
53 changes: 30 additions & 23 deletions 4_Conceptos/4_Entidad.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,47 @@

## Entidad

Este documento está basado en [^1].
Este documento está basado en [^2] y [^1].

[^2]: Evans, E. (2015). Domain-Driven Design Reference: Definitions and Pattern
  Summaries. Domain Language, Inc. Disponible
  [aquí](https://www.domainlanguage.com/wp-content/uploads/2016/05/DDD_Reference_2015-03.pdf).

[^1]: Avram, A; Marinescu, F. (2006). Domain-Driven Design Quickly. InfoQ.
Disponible
[aquí](https://www.infoq.com/minibooks/domain-driven-design-quickly/).

En el contexto de *Domain-Driven Design* —DDD, por sus siglas—, una entidad es
un objeto cuya identidad se mantiene constante durante los diferentes estados de
un sistema, de hecho, las entidades tienen una identidad que abarca la vida de
un sistema y puede extenderse más allá del mismo.
un objeto que se distingue por su identidad, en lugar de por sus atributos. Es
necesario un mecanismo para diferenciar un objeto de otro independientemente de
su forma[^3] o su historia.

[^3]: Por ejemplo cuando se transforma a una representación para almacenamiento
persistente o para ser enviado a través de la red.

Así es que implementar entidades en software implica crear identidades, por lo
que la capacidad de identificar estas últimas es crucial. Por ejemplo, si
quisieras implementar la entidad `Persona`, podrías plantearte utilizar algún
atributo en particular como su nombre, o incluso un conjunto de ellos, ya que no
sería suficiente con simplemente usar su nombre y su fecha de nacimiento, por
mencionar una combinación. Tampoco sería suficiente utilizar su lugar de
nacimiento, ya que diferentes personas podrían tener el mismo lugar de
nacimiento; lo importante aquí es encontrar el atributo o combinación de
atributos que garantizan la identidad de la entidad `Persona`, ya que la mala
identificación de una entidad puede llevar a la corrupción de datos.

La cédula de identidad es un atributo que garantiza al identidad de una
`Persona`, por lo que puede ser utilizado para crear la identidad de `Persona`.
Usualmente, la identidad es un atributo del objeto, una combinación de
atributos, un atributo generado automática y específicamente para expresar la
identidad —un atributo `id`, por ejemplo—, o incluso un comportamiento. Para
evitar que todo el sistema se vuelva corrupto, es importante que se cumplan las
que la capacidad de identificar estas últimas es crucial. El atributo —o
combinación de atributos— utilizado para lograr la identidad puede ser propio
del objeto, asignado por alguien externo a la aplicación o incluso al
[dominio](./4_Dominio.md). Pero a veces no hay ninguna combinación de atributos
que permita identificar los objetos de forma única, por lo que se puede utilizar
un sistema arbitrario creado por la aplicación.

Por ejemplo, para una entidad `Persona`, es casi seguro que ninguna combinación
de los atributos nombre, fecha y lugar de nacimiento, permita identificar en
forma única a una persona, pues diferentes personas pueden tener el mismo
nombre, la misma fecha, y el mismo lugar de nacimiento. En cambio, la cédula de
identidad, asignada por la autoridad de identificación civil, que es externa a
la aplicación, garantiza que no hay dos personas con la misma cédula, por lo que
podría ser utilizado para lograr la identidad.

Una mala elección del mecanismo para lograr identificar a una entidad puede
llevar a la corrupción de datos. Para evitarlo, es importante que se cumplan las
siguientes dos condiciones:

* Dos objetos con diferentes identidades son considerados diferentes por el
sistema
* Dos objetos con diferentes identidades son considerados diferentes

* Dos objetos con la misma identidad son considerados el mismo por el sistema
* Dos objetos con la misma identidad son considerados el mismo

Cuando un objeto es diferenciado por su identidad, debes hacerla primaria en la
definición de la entidad en el modelo. Además, debes estar pendiente a los
Expand Down
51 changes: 51 additions & 0 deletions 4_Conceptos/4_Evento_del_dominio.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Conceptos

## Evento del dominio

Este documento está basado en [^2] y [^1].

[^2]: Evans, E. (2015). Domain-Driven Design Reference: Definitions and Pattern
  Summaries. Domain Language, Inc. Disponible
  [aquí](https://www.domainlanguage.com/wp-content/uploads/2016/05/DDD_Reference_2015-03.pdf).

[^1]: Avram, A; Marinescu, F. (2006). Domain-Driven Design Quickly. InfoQ.
Disponible
[aquí](https://www.infoq.com/minibooks/domain-driven-design-quickly/).

Una [entidad](./4_Entidad.md) es responsable de conocer y manipular sus datos a
lo largo de su ciclo de vida. Aunque típicamente no son explícitas las causas de
los cambios en el estado de las entidades y puede ser difícil explicar cómo la
aplicación llegó a tener los valores que tiene en un momento dado.

Otro tema diferente, pero relacionado, son las cuestiones que aparecen en los
sistemas distribuidos, en los que el estado no siempre es consistente
[consistencia eventual](https://en.wikipedia.org/wiki/Eventual_consistency)—.
Mientras que en los [agregados](./4_Agregado.md) se puede mantener la
consistencia internamente, otros cambios deben ser asíncronos y propagarse a
través de la red.

Para definir eventos del dominio, considera lo siguiente:

* Modela la información acerca de una actividad en el [dominio](./4_Dominio.md)
como una serie de **eventos discretos**.

* Representa cada evento como un objeto del dominio.

Un evento de dominio es una parte completa del modelo de dominio, una
representación de algo que sucedió en el dominio. Compáralo con [evento del
negocio](./4_Evento_del_negocio.md). Ignora la actividad irrelevante del
dominio, mientras haces explícitos los eventos a los que los expertos del
dominio desean responder, o de los que desean recibir notificaciones, o que
están asociados con el cambio de estado en los otros objetos del modelo.

En un sistema distribuido, el estado de una entidad se puede inferir a partir de
los eventos de dominio actualmente conocidos por un nodo particular, lo que
permite un modelo coherente en ausencia de información completa sobre el sistema
en su conjunto.

Mira cómo este concepto interviene en el patrón Event Sourcing
[aquí](https://martinfowler.com/eaaDev/EventSourcing.html) o
[aquí](https://learn.microsoft.com/en-us/azure/architecture/patterns/event-sourcing),
y en el patrón CQRS o *Command Query Responsibility Segregation*
[aquí](https://martinfowler.com/bliki/CQRS.html) o
[aquí](https://learn.microsoft.com/en-us/azure/architecture/patterns/cqrs).
4 changes: 3 additions & 1 deletion 4_Conceptos/4_Evento_del_negocio.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@

Los eventos del negocio son cosas que suceden y —a su vez— hacen que el
[trabajo](/4_Conceptos/4_Trabajo_y_area_de_trabajo.md) responda de alguna
manera[^1]. Un evento puede ocurrir fuera del alcance del trabajo —un evento
manera[^1]. Compáralo con [evento del dominio](./4_Evento_del_dominio.md).

Un evento puede ocurrir fuera del alcance del trabajo —un evento
externo—, o puede suceder porque es el momento de que el trabajo haga algo —un
evento desencadenado por el tiempo—.

Expand Down
50 changes: 27 additions & 23 deletions 4_Conceptos/4_Factory.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,44 @@

## *Factory*

Este documento está basado en [^1].
Este documento está basado en [^2] y [^1].

[^2]: Evans, E. (2015). Domain-Driven Design Reference: Definitions and Pattern
  Summaries. Domain Language, Inc. Disponible
  [aquí](https://www.domainlanguage.com/wp-content/uploads/2016/05/DDD_Reference_2015-03.pdf).

[^1]: Avram, A; Marinescu, F. (2006). Domain-Driven Design Quickly. InfoQ.
Disponible
[aquí](https://www.infoq.com/minibooks/domain-driven-design-quickly/).

Las [entidades](./4_Entidad.md) y los [agregados](./4_Agregado.md) pueden ser
muy complejos como para que sean creados por la entidad raíz, y dejar en la raíz
la responsabilidad de crear un agregado complejo va usualmente en contradicción
de lo que pasa en el [dominio](./4_Dominio.md). Además, cuando el proceso de
crear otro objeto es laborioso, involucra tener conocimiento sobre la estructura
interna del objeto a crear y sus relaciones con otros objetos, rompiendo el
encapsulamiento de los objetos y agregados del dominio.

Una *Factory* —fábrica, en español— es un concepto utilizado para encapsular el
muy complejos como para que sean creados por la entidad raíz; o crear y
ensamblar objetos complejos no es una responsabilidad que pueda ser asignada a
los objetos creados, o puede producir diseños poco elegantes y difíciles de
entender. Hacer que el cliente dirija la construcción de esos objetos enturbia
el diseño del cliente, viola el encapsulamiento del objeto ensamblado o agregado
—requiere que el cliente conozca la estructura interna y las relaciones con
otros objetos— y vincula excesivamente al cliente con la implementación del
objeto creado.

Una *Factory* —fábrica, en español— es una clase utilizada para encapsular el
conocimiento necesario para la creación de objetos, y es especialmente útil para
la creación de agregados.

Es importante que el proceso de creación de objetos sea atómico para evitar que
los objetos creados estén incompletos. Para los agregados, esto significa que
cuando la raíz sea creada, todos los objetos del agregado sujetos a invariantes,
deben ser creados también para que las mismas se puedan cumplir. Para los
la creación de agregados y objetos complejos. En una *Factory* se desplaza la
responsabilidad de crear agregados y objetos complejos a un nuevo objeto que
puede no tener responsabilidad alguna en el modelo del dominio pero aún así
forma parte del diseño del dominio. Provee una interfaz que encapsula la lógica
compleja del ensamblado y crea agregados enteros como una unidad, cumpliendo
entonces con sus invariantes.

Es importante que el proceso de creación de objetos sea atómico —todo o nada—
para evitar que los objetos creados estén incompletos. Para los agregados, esto
significa que cuando la raíz sea creada, todos los objetos también deben ser
creados de forma tal que se cumplan las invariantes que hubiera. Para los
[objetos valor](./4_Objeto_Valor.md), esto significa que todos los atributos son
inicializados en su estado válido. Para evitar que un valor inválido sea creado,
inicializados en su estado válido. Para evitar que sea creado un valor inválido,
se debe arrojar una excepción cuando un objeto no puede ser creado
apropiadamente.

> [!NOTE]
> Desplaza la responsabilidad de crear agregados y objetos complejos a un nuevo
> objeto que puede no tener responsabilidad alguna en el modelo del dominio pero
> aún así forma parte del diseño del dominio. Provee una interfaz que encapsula
> la lógica compleja del ensamblado y crea agregados enteros como una unidad,
> cumpliendo entonces sus invariantes.
Existen varios patrones de diseño para implementar *Factories*, por ejemplo:
[*Factory Method*](https://refactoring.guru/design-patterns/factory-method) y
[*Abstract Factory*](https://refactoring.guru/design-patterns/abstract-factory).
Expand Down
33 changes: 17 additions & 16 deletions 4_Conceptos/4_Modulo.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

## Módulo en *Domain-Driven Design*

Este documento está basado en [^1].
Este documento está basado en [^2] y [^1].

[^2]: Evans, E. (2015). Domain-Driven Design Reference: Definitions and Pattern
  Summaries. Domain Language, Inc. Disponible
  [aquí](https://www.domainlanguage.com/wp-content/uploads/2016/05/DDD_Reference_2015-03.pdf).

[^1]: Avram, A; Marinescu, F. (2006). Domain-Driven Design Quickly. InfoQ.
Disponible
Expand All @@ -15,7 +19,7 @@ conceptos y tareas relacionadas con el fin de reducir la complejidad del modelo.

Los módulos son una forma sencilla y eficaz de manejar la complejidad y se usan
en la mayoría de proyectos. Para entender un modelo con módulos, primero se
obtiene una imagen general observando los módulos y sus relaciones y luego se
obtiene una imagen general observando los módulos y sus relaciones, y luego se
puede entrar en más detalle adentrándose en un módulo específicamente.

Los módulos también favorecen a la calidad del código al proveer mayor
Expand All @@ -25,21 +29,18 @@ definen interfaces bien definidas para los módulos, de modo que los módulos
interactúan a través de ellas, en vez de interactuar con varias clases
directamente.

> [!TIP]
> Elije módulos que cuenten la historia del sistema y contengan un conjunto de
> conceptos cohesivos.
Para definir módulos, puedes considerar las siguientes recomendaciones:

* Elije módulos que cuenten la historia del sistema y contengan un conjunto de
conceptos cohesivos.

> [!TIP]
> Busca reducir el acoplamiento entre módulos creando módulos que puedan ser
> razonados de forma independiente entre ellos.
* Busca reducir el acoplamiento entre módulos creando módulos que puedan ser
razonados de forma independiente entre ellos.

> [!TIP]
> Refina el modelo hasta que sea particionado en conceptos de alto nivel y su
> código sea desacoplado.
* Refina el modelo hasta que sea particionado en conceptos de alto nivel y su
código sea desacoplado.

> [!TIP]
> Nombra los módulos utilizando el lenguaje ubicuo.
* Nombra los módulos utilizando el lenguaje ubicuo.

> [!TIP]
> Es recomendado que los módulos sean algo flexibles para que puedan evolucionar
> junto al proyecto.
* Es recomendado que los módulos sean algo flexibles para que puedan evolucionar
junto al proyecto.
Loading

0 comments on commit 5d1c17d

Please sign in to comment.