Sobes.tech
Middle+

Cos'è un aggregato?

sobes.tech AI

Risposta dell'AI

L'aggregato nel design orientato agli oggetti (DDD) è un raggruppamento di oggetti correlati considerati come un'unità in termini di integrità dei dati. Ogni aggregato ha un oggetto radice (Root dell'Aggregato), che è l'unico punto di accesso agli altri oggetti all'interno dell'aggregato. Tutte le modifiche all'interno dell'aggregato devono essere effettuate tramite l'oggetto radice per mantenere gli invarianti (regole di integrità).

Caratteristiche chiave:

  • Oggetto radice (Root dell'Aggregato): L'unico punto di accesso ai componenti dell'aggregato.
  • Incapsulamento: Gli oggetti interni dell'aggregato non devono essere accessibili direttamente dall'esterno.
  • Limite di coerenza: L'aggregato definisce un limite entro il quale vengono mantenuti gli invarianti. Le modifiche all'interno dell'aggregato sono coerenti transazionalmente.
  • Isolamento: Non è possibile interagire direttamente con gli oggetti di un altro aggregato, solo tramite i loro oggetti radice o tramite servizi del dominio.

Esempio:

<?php

// Oggetto radice dell'aggregato "Ordine"
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
    {
        // Verifica degli invarianti, ad esempio, quantità > 0
        if ($quantity <= 0) {
            throw new InvalidArgumentException("La quantità deve essere maggiore di zero.");
        }

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

    public function confirm(): void
    {
        // Verifica degli invarianti prima di cambiare lo stato
        if ($this->status !== OrderStatus::Pending) {
            throw new DomainException("L'ordine non è più nello stato 'In attesa'.");
        }

        // Logica di conferma, ad esempio, verifica disponibilità dei prodotti
        $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;
    }
}

// Oggetto interno dell'aggregato "Voce dell'ordine"
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;
    }
}

// Oggetti di valore (come esempio)
final class OrderId {}
final class CustomerId {}
final class ProductId {}
final class Money {}
enum OrderStatus { case Pending; case Confirmed; case Cancelled; }