Cet article est un résumé de la conception efficace d'agrégats, partie I: Modélisation d'un seul agrégat .
Combiner des entités et des objets de valeur dans un agrégat avec des limites de cohérence soigneusement pensées peut sembler simple, mais de tous les modèles DDD tactiques, l'agrégat est l'un des plus complexes.
Il sera utile de commencer par quelques questions générales. Un agrégat est-il simplement un moyen de combiner des objets étroitement liés avec une racine commune (racine d'agrégat)? Si oui, y a-t-il une sorte de limitation sur le nombre d'objets qui peuvent être dans le graphique? Puisqu'un agrégat peut faire référence à un autre, est-il possible de parcourir les agrégats à l'aide de ces liens et de modifier les données des objets inclus dans un agrégat particulier? Et quel est l' invariant et la limite de cohérence ? La réponse à la dernière question influence largement le reste des réponses.
Il existe de nombreuses façons de modéliser un assemblage de manière incorrecte. Nous pouvons concevoir une unité trop grande. D'un autre côté, nous pouvons diviser tous les agrégats de manière à ce que les vrais invariants soient violés. Comme nous le verrons, il est impératif d'éviter de tels extrêmes et de prêter plutôt attention aux règles métier.
Développement d'applications ProjectOvation
Jetons un coup d'œil aux agrégats avec un exemple. Notre société fictive développe une application de support de projets basée sur la méthodologie Scrum. L'application suit le modèle de gestion de projet Scrum traditionnel, c'est-à-dire qu'il existe un produit (produit), un propriétaire de produit (propriétaire de produit), des équipes (équipe), des éléments de backlog (éléments de backlog), des versions planifiées (versions planifiées), des sprints ( sprints). La terminologie Scrum constitue le point de départ d' un langage omniprésent. Chaque organisation qui achète un abonnement s'enregistre en tant que locataire, un autre terme pour notre langage commun .
. , 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;
...
}
, - . , . , . , , . () , .
:
, , Product c 1 .
BacklogItem . 2.
Release , , Product 1.
. .
. , . . .
. ? , -. , . , .
:
, 2. . ProductId, 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 .
. , , . , , , - . , , .
, . , .
— -, . . , . . . :
, , = 2 b = 3, 5. , 5, . , , .
AggregateType1 {
int a; int b; int c;
operations...
}
, , , - , . , , . , .
. , , . – , , , , . .
( ) . .
, , , . , . . . , , .
: ? , , . , , , , , . - , .
, , ? , (lazy loading). , . , , . , . , , . , .
, 3. 0..* . . , . . , , . .
. , , .
, , «». , , , . , (root entity), / (object value).
, (, ) ? : , . , Product name description. , . , , . -, .
, , , . , , . , , , . , . . - , .
. , . , . , . Order OrderItem . , - , . , .
, , . . , , , .
, . , - . , . , . , , .
, -, , - , . 4. , , , . . , . , , , -.
, , . , , . ?
, , , , . - (eventual consistency) . , , , . , , . . , .