Oyun Kitabı

Code DDD : entité, objet de valeur et agrégat (Code Ddd Entite Objet DE Valeur Et Agregat)

Comment fonctionnent les modèles tactiques DDD ? Limites de l'objet de valeur, de l'entité, de l'agrégat, du service de domaine, du service d'application et du référentiel avec un exemple de commande réelle…

DDD - Langage commercial du logiciel

Partie 2 de 4

DDD tactical patterns showing value objects, entities, and aggregate boundaries

Question de cet article

Dans la première partie, nous sommes partis du langage et des règles de l’entreprise. Maintenant, la question est : où conservons-nous ces décisions dans le code ? Nous utiliserons le même domaine e-commerce : argent, ligne de commande, flux de commande et de paiement.```text Money + Address + Quantity → Value Object OrderLine + Order → Entity Order (Root) + OrderLine → Aggregate Repository → Aggregate Root'u yükler ve kaydeder


## Concepts à la première mention```text
📦 Value Object
Kimliği olmayan, değeriyle tanımlanan ve değişmez tutulması gereken kavram.

📦 Entity
Nitelikleri değişse de kimliği boyunca aynı kalan nesne.

📦 Aggregate
Birlikte tutarlı kalması gereken nesnelerin transaction sınırı.

📦 Aggregate Root
Aggregate'e dışarıdan girilebilen tek kapı.
```Par exemple, deux `Money(100, "TRY")` représentent la même valeur ; Deux commandes ont des identités différentes même si leurs sommes sont les mêmes.

## Commencer par l'objet valeur

Value Object enseigne le mieux la façon de penser en DDD. `decimal` n'est pas de l'argent en soi : il comporte des règles de devise, d'arrondi, de remise et de fiscalité. Stockez ces règles dans le concept plutôt que de les distribuer à la couche service.```csharp
public sealed record Money(decimal Amount, string Currency)
{
    public Money Add(Money other)
    {
        if (Currency != other.Currency) throw new DomainException("Currency mismatch");
        return new Money(Amount + other.Amount, Currency);
    }
}
```L'objet de valeur est immuable : lorsque la valeur change, une nouvelle instance est créée. Ainsi, la même adresse, e-mail, plage de dates ou valeur monétaire ne produit pas d’effets secondaires inattendus dans les différentes étapes de transaction. La comparaison est effectuée en fonction du contexte ; Par conséquent, le coût d’égalité est O(m) avec le nombre de champs, mais le coût de modification diminue car la règle métier reste au même endroit.

## Entité : identité et cycle de vie

`Order` est une entité. Peut changer son adresse ou son total ; C'est toujours le même ordre. La différence ne réside pas dans l'utilisation de setters, mais dans la modélisation de la transition en tant que comportement au travail.```text
❌ order.Status = Paid
✓ order.ConfirmPayment(payment)

❌ order.Total = total - discount
✓ order.ApplyDiscount(discount)
````ConfirmPayment` vérifie en un seul endroit comme preuve de paiement, que la commande n'a pas été annulée et que la transition est légale. La tâche de l'entité n'est pas de déplacer toutes les données, mais d'éviter les situations invalides au cours de son cycle de vie.

## Agrégat : pas un groupe d'objets, mais une limite de cohérence

La commande et ses lignes doivent rester cohérentes au sein d'une même transaction : le nombre de lignes est positif, le total est égal à la somme des lignes, et la ligne ne peut plus être modifiée une fois la commande confirmée. Ainsi, `Order` devient la racine agrégée pour `OrderLine`.```text
Order aggregate
  ├─ OrderLine
  ├─ ShippingAddress
  └─ Total

Dış dünya → Order.AddLine() / Order.ConfirmPayment()
Dış dünya ↛ OrderLine'a doğrudan yazmaz
```Rendre Aggregate grand produit des verrous et des conflits de versions, pas de sécurité. Mettez à jour le plus grand agrégat possible dans la demande d'écriture. Connectez-vous à un autre agrégat par ID au lieu de référence d'objet ; Si une coordination est requise, utilisez l’orchestration d’événements de domaine ou d’applications. Cela limite les conflits de concurrence optimistes et les coûts d’installation inutiles.

## Service de domaine et service d'application

Si une règle n'appartient pas naturellement à un seul Agrégat, il peut s'agir d'un Service de Domaine : par exemple, une tarification basée sur le taux de change. En revanche, le service d'application gère le cas d'utilisation : charge la commande, appelle le comportement, l'enregistre et termine la transaction.

| Couche | Responsabilité |
| --- | --- |
| Objet de valeur / Entité / Agrégat | Maintien des règles métier et des invariants |
| Service de domaine | Compte de domaine pur n'appartenant pas à Aggregate |
| Service de candidatures | Orchestration de cas d'utilisation, appels de transactions et d'adaptateurs |

Mettre des règles dans Application Service est un retour du modèle anémique à la couche service.

## Dépôt : pas d'API de table

Le référentiel donne au domaine la sensation d'une collection en mémoire ; Ce n'est pas un détail SQL ou ORM. Au lieu de créer un référentiel pour chaque table, utilisez-le uniquement pour les racines agrégées. Le remplacement direct de l'entité enfant par `OrderLineRepository.Find()` contourne les règles maintenues par Root.```text
order = orderRepository.get(orderId)
order.confirmPayment(payment)
orderRepository.save(order)
```Cette limite permet également une vérification indépendante de l'infrastructure du comportement du domaine avec un référentiel fictif lors des tests. Le constructeur vide d'ORM ou l'exigence de chargement rapide ne devraient pas façonner le modèle de domaine ; Le mappage relève de la responsabilité de l'adaptateur.

## Correspondances qui créent une fausse confiance```text
❌ Value Object = küçük DTO
✓ Value Object değer, doğrulama ve davranış taşır.

❌ Aggregate = mümkün olduğunca büyük nesne grafiği
✓ Aggregate = küçük tutulmuş transaction ve consistency boundary.

❌ Domain Service = iş kuralı çöplüğü
✓ Yalnızca tek Aggregate'e ait olmayan saf domain davranışı.

❌ Repository = her tablo için CRUD API
✓ Repository = Aggregate Root'un kalıcılık sınırı.

Liste de contrôle de candidature

  1. Des concepts tels que Money, Email, Address, Quantity circulent-ils en tant que primitifs ?
  2. Chaque comportement d'entité empêche-t-il réellement un état invalide ?
  3. Une demande d'écriture tente-t-elle de mettre à jour atomiquement plusieurs agrégats ?
  4. Le service applicatif prend-il des décisions ou orchestre-t-il simplement ?
  5. Le référentiel installe-t-il uniquement les racines agrégées ?

Commencez par la règle métier la plus coûteuse ; Ne transformez pas l'ensemble du système en DDD tactique d'un seul coup.

Ce qu'il faut retenir de cet article

Value Object porte la valeur et les règles du concept. L'entité conserve son identité et son cycle de vie. Aggregate définit une petite limite de transaction pour des raisons de cohérence. Le référentiel rassemble cette limite avec la permanence.

L'objectif du DDD tactique n'est pas d'ajouter plus de classes, mais d'empêcher la règle métier de s'infiltrer dans la mauvaise couche.

Dans la section suivante, nous examinerons comment parler de ces frontières dans un système plus large : contexte délimité, cartographie du contexte et décomposition au sein du monolithe.

FAQ

Frequently asked questions

Qu'est-ce qu'un objet de valeur ?

Un concept qui n'a pas d'identité, est défini par sa valeur et doit rester constant.

Qu’est-ce que l’entité ?

Un objet qui reste le même tout au long de son identité même si ses qualités changent.

"Value Object = small DTO" est-il correct ?

L'objet de valeur comporte de la valeur, une validation et un comportement.

Que corrige cette section ?

Dans la première partie, nous sommes partis du langage et des règles de l’entreprise. Maintenant, la question est : où conservons-nous ces décisions dans le code ? Nous utiliserons le même domaine e-commerce : argent, ligne de commande, flux de commande et de paiement. Dans la première partie, nous sommes partis du langage et des règles de l’entreprise. Maintenant, la question est : où conservons-nous ces décisions dans le code ? Nous utiliserons le même domaine e-commerce : argent, ligne de commande, flux de commande et de paiement.

Principes d'ingénierie appris

  • Value Object combine des données primitives avec la sémantique métier et la validation.
  • L'agrégat doit être petit et avoir une limite de cohérence claire.
  • Le service d'application gère le processus ; le comportement du domaine décide.

Continuer la lecture

Continuer la lecture

Suivant en série

Suivant en série

Même série

Paylaş