Sobes.tech
Middle+

Qu'est-ce qu'un agrégat?

sobes.tech IA

Réponse de l'IA

L'agrégat dans la conception orientée objet (DDD) est un groupe d'objets liés considérés comme une unité en termes d'intégrité des données. Chaque agrégat possède un objet racine (Racine de l'Agrégat), qui est le seul point d'accès aux autres objets à l'intérieur de l'agrégat. Toutes les modifications à l'intérieur de l'agrégat doivent être effectuées via l'objet racine pour maintenir les invariants (règles d'intégrité).

Caractéristiques clés:

  • Objet racine (Racine de l'Agrégat): Le seul point d'accès aux composants de l'agrégat.
  • Encapsulation: Les objets internes de l'agrégat ne doivent pas être accessibles directement de l'extérieur.
  • Limite de cohérence: L'agrégat définit une limite à l'intérieur de laquelle les invariants sont maintenus. Les changements à l'intérieur de l'agrégat sont transactionnellement cohérents.
  • Isolation: Il n'est pas possible d'interagir directement avec les objets d'un autre agrégat, seulement via leurs objets racine ou par des services du domaine.

Exemple:

<?php

// Objet racine de l'agrégat "Commande"
class Order
{
    private OrderId $id;
    private CustomerId $customerId;
    /** @var OrderItem[] */
    private array $items = [];
    private OrderStatus $status;

    public function __construct(OrderId $id, CustomerId $customerId)
    {
        $this->id = $id;
        $this->customerId = $customerId;
        $this->status = OrderStatus::Pending;
    }

    public function addItem(ProductId $productId, int $quantity, Money $price): void
    {
        // Vérification des invariants, par exemple, quantité > 0
        if ($quantity <= 0) {
            throw new InvalidArgumentException("La quantité doit être supérieure à zéro.");
        }

        $this->items[] = new OrderItem($productId, $quantity, $price);
    }

    public function confirm(): void
    {
        // Vérification des invariants avant de changer le statut
        if ($this->status !== OrderStatus::Pending) {
            throw new DomainException("La commande n'est plus en statut 'En attente'.");
        }

        // Logique de confirmation, par exemple, vérification de la disponibilité des produits
        $this->status = OrderStatus::Confirmed;
    }

    public function getId(): OrderId
    {
        return $this->id;
    }

    public function getStatus(): OrderStatus
    {
        return $this->status;
    }

    /** @return OrderItem[] */
    public function getItems(): array
    {
        return $this->items;
    }
}

// Objet interne de l'agrégat "Ligne de commande"
class OrderItem
{
    private ProductId $productId;
    private int $quantity;
    private Money $price;

    public function __construct(ProductId $productId, int $quantity, Money $price)
    {
        $this->productId = $productId;
        $this->quantity = $quantity;
        $this->price = $price;
    }

    public function getProductId(): ProductId
    {
        return $this->productId;
    }

    public function getQuantity(): int
    {
        return $this->quantity;
    }

    public function getPrice(): Money
    {
        return $this->price;
    }
}

// Objets de valeur (exemple)
final class OrderId {}
final class CustomerId {}
final class ProductId {}
final class Money {}
enum OrderStatus { case Pending; case Confirmed; case Cancelled; }