Diseño de unidad eficiente. Simulación de una sola unidad

Este artículo es una sinopsis de Diseño de agregado efectivo Parte I: Modelado de un solo agregado .





Combinar entidades y objetos de valor en un agregado con límites de consistencia cuidadosamente pensados ​​puede parecer simple, pero de todos los patrones tácticos de DDD, el agregado es uno de los más complejos.





Será útil comenzar con algunas preguntas generales. ¿Es un agregado solo una forma de combinar objetos estrechamente relacionados con una raíz común (Raíz agregada)? Si es así, ¿existe algún tipo de limitación en la cantidad de objetos que pueden estar en el gráfico? Dado que un agregado puede hacer referencia a otro, ¿es posible navegar por los agregados utilizando estos enlaces y cambiar los datos de los objetos incluidos en un agregado en particular? ¿Y cuál es el invariante y el límite de consistencia ? La respuesta a la última pregunta influye en gran medida en el resto de las respuestas.





Hay muchas formas de modelar incorrectamente un ensamblaje. Podemos diseñar una unidad que sea demasiado grande. Por otro lado, podemos dividir todos los agregados de tal manera que, como resultado, se violen las verdaderas invariantes. Como veremos, es imperativo evitar tales extremos y prestar atención a las reglas comerciales.





Desarrollo de aplicaciones ProjectOvation

Echemos un vistazo a los agregados con un ejemplo. Nuestra empresa ficticia está desarrollando una aplicación para apoyar proyectos basada en la metodología Scrum. La aplicación sigue el modelo tradicional de gestión de proyectos Scrum, es decir, hay un producto (producto), un propietario de producto (propietario de producto), equipos (equipo), elementos de la lista de trabajos pendientes (elementos de la lista de trabajos pendientes), lanzamientos planificados (lanzamientos planificados), sprints ( sprints). La terminología de Scrum constituye el punto de partida de un lenguaje ubicuo. Cada organización que compra una suscripción se registra a sí misma como inquilino, otro término para nuestro lenguaje común .





. , DDD . , , DDD . , . , .





? . , . . :





  • , .





  • .





  • .





  • .





  • .





  • .





. , .





:

« » . , , . :





  • , .





  • , .





  • , .





  • , .





Product . , Product, BacklogItem, Release, Sprint , . . UML- .





public class Product extends ConcurrencySafeEntity {

    private Set<BacklogItem> backlogItems;
    private String description;
    private String name;
    private ProductId productId;
    private Set<Release> releases;
    private Set<Sprint> sprints;
    private TenantId tenantId;
    ...

}

      
      



Figura:  1. El producto se modela como un conjunto muy grande.
. 1. Product .

, - . , .  , . , , . () , .





:





  • , , Product c 1 .





  • BacklogItem . 2.





  • Release , , Product 1.





. .





. , . . .





. ? , -. , . , .





:

, 2. . ProductId, Product-.





Figura:  2. El producto y los conceptos relacionados se modelan como agregados separados.
. 2. Product .

Product. :





public class Product ... {
    	...
      public void planBacklogItem(
        String aSummary, String aCategory,
        BacklogItemType aType, StoryPoints aStoryPoints) {
      		...
      }
    	...
      public void scheduleRelease(
        String aName, String aDescription,
        Date aBegins, Date anEnds) {
      		...
      }

      public void scheduleSprint(
        String aName, String aGoals,
        Date aBegins, Date anEnds) {
        	...
      }
      ...
}

      
      



. Product, , – void. :





public class Product ... {
    	...
      public BacklogItem planBacklogItem(
        String aSummary, String aCategory,
        BacklogItemType aType, StoryPoints aStoryPoints) {
      		...
      }
  
      public Release scheduleRelease(
        String aName, String aDescription,
        Date aBegins, Date anEnds) {
        	...
      }

      public Sprint scheduleSprint(
        String aName, String aGoals,
        Date aBegins, Date anEnds) {
        	...
      }
      ...
}

      
      



. . , , :





public class ProductBacklogItemService ... {
     ...
     @Transactional
     public void planProductBacklogItem(
           String aTenantId, String aProductId,
           String aSummary, String aCategory,
           String aBacklogItemType, String aStoryPoints) {

           Product product =
                   productRepository.productOfId(
                                 new TenantId(aTenantId),
                                new ProductId(aProductId));

           BacklogItem plannedBacklogItem =
                  product.planBacklogItem(
                            aSummary,
                            aCategory,
                            BacklogItemType.valueOf(aBacklogItemType),
                            StoryPoints.valueOf(aStoryPoints));
          
          backlogItemRepository.add(plannedBacklogItem);
      }
      ...
}

      
      



, . BacklogItem, Release Sprint .





. , , . , , , - . , , .





, . , .





— -, . . , . . . :





c = a + b

, , = 2 b = 3, 5. , 5, . , , .





AggregateType1 {
    int a; int b; int c;
    operations...
}

      
      



, , , - , . , , . , .





. , , . – , , , , . .





( ) . .





, , , . , . . . , , .





: ? , , . , , , , , . - , .





, , ? , (lazy loading). , . , , . , . , , . , .





, 3. 0..* . . , . . , , . .





Figura:  3. Modelo de producto.  Varias colecciones grandes se cargan durante muchas operaciones simples.
. 3. Product. .

. , , .





, , «». , , , . , (root entity), / (object value).





, (, ) ? : , . , Product name description. , . , , . -, .





, , , . , , . , , , . , . . - , .





. , . , . , . Order OrderItem . , - , . , .





, , . . , , , .





, . , - . , . , . , , .





, -, , - , . 4. , , , . . , . , , , -.





Figura:  4. Muestra el acceso simultáneo a los datos entre tres usuarios.  Intentan acceder a las mismas dos instancias de agregados, lo que genera una gran cantidad de errores de transacción.
. 4. . , .

, , . , , . ?





, , , , . - (eventual consistency) . , , , . , , . . , .








All Articles