Troppo strong dell'accoppiamento tra radici aggregate?

1

Nel tentativo di salvare questa domanda, l'ho riscritta. La domanda originale riguardava come associare le radici aggregate. Ho rielaborato leggermente il codice ma credo che questo possa accoppiare il codice troppo strettamente.

Introduco troppo stretto l'accoppiamento facendo passare le radici aggregate? Ad esempio:

class Order
{
    public Order(int customerId, Address billing, Address shipping, List<Items> items)
    {
        _customerId = customerId;
        _billing = billing;
        _shipping = shipping
        _items = items;
    }

    private int _id;
    private Address _billing;
    private Address _shipping;
    private List<Item> _items;
}

class Customer
{
    public Order PlaceOrder(List<Item> items)
    {
        return new Order(_id, _billingAddress, _shippingAddress, items);
    }

    private int _id;
}

class Cart
{
    public Order Checkout(Customer customer)
    {
        var items = _items.ToList();
        _items.Clear();

        return customer.PlaceOrder(_items.ToList());
    }

    public AddItem(Product product, int quantity)
    {
        // Add item to cart
    }

    public RemoveItem(Product product, int quantity)
    {
        // Remove item from cart
    }

    private List<Item> _items = new List<Item>();
}

Quindi nel mio livello di servizio applicativo per un cliente per il checkout avrei qualcosa del tipo:

public CustomerCheckoutService
{
    public void Checkout(int customerId)
    {
        var customer = _customerRepo.GetById(customerId);

        CompletePurchase(customer);
    }

    public void Checkout(int customerId, Address newShipping)
    {
        var customer = _customerRepo.GetById(customerId);

        customer.UpdateShipping(newShipping);

        CompletePurchase(customer);
    }

    private void MakePurchase(Customer customer)
    {
        var cart = _cartRepo.GetByCustomer(customerId);

        var order = cart.Checkout(customer);

        _orderRepo.Save(order);
        _cartRepo.Save(cart);
    }
}

Mi sembra che ci sia un sacco di accoppiamenti tra i miei aggregati e ognuno di loro ha bisogno l'uno dell'altro.

    
posta keelerjr12 05.12.2018 - 13:05
fonte

1 risposta

1

Il tuo dominio sembra ok tranne che sappiamo che Cart non CheckOut stesso. Destra? CheckOut rappresenta più un caso d'uso che una qualsiasi mutazione dati specifica. "Checking out" è un processo con il quale una Customer si impegna come mezzo per condurre alcune transazioni commerciali ( PlaceOrder ). Come tale, ha più senso mantenere questa conoscenza nel livello dell'applicazione. Inoltre, spesso diversi modi / tipi di "check-out" iniziano a sorgere mentre un'azienda si sviluppa.

Il tuo servizio può essere semplificato a qualcosa di simile:

// CheckOutCommandHandler

purchaseRequest = purchaseRequests.Find( cmd.CustomerId )

customer = customers.Find( cmd.CustomerId )

order = customer.PlaceOrder( purchaseRequest ) // raise OrderPlaced

orders.save( order )

Dato che hai Cart e Customer in diversi contesti limitati, abbiamo davvero bisogno di introdurre un nuovo concetto nel tuo contesto Ordine che possa contenere le informazioni necessarie a PlaceOrder . In questo caso, lo chiamo PurchaseRequest .

Nel suo nucleo, penso che la tua incertezza sia fondata su una certa confusione riguardante in che modo le diverse entità con cui lavori si relazionano l'una con l'altra. In particolare, in che modo i contesti Shopping e Order possono condividere dati tra loro. Ciò si traduce nel passaggio di più dati in giro del necessario e un sacco di doppia spedizione (entrambe le forme di accoppiamento).

È fondamentale capire che il tuo modello data (il tuo database) non ha concetto di "contesti limitati". Questo ha senso perché un database non ha alcun comportamento (che è il modo in cui sono organizzati i contesti limitati). Il risultato è che un Cart e un PurchaseRequest vengono idratati usando gli stessi stessi ! La differenza è che un Cart rappresenta un'entità contesto Shopping che è responsabile dell'aggiunta / rimozione di elementi e un PurchaseRequest rappresenta un oggetto del valore di contesto Ordine che è copiato in un nuovo Order quando posto. Inoltre, potrebbe essere un luogo in cui conservare un indirizzo di spedizione alternativo, codici coupon, ecc.

    
risposta data 06.12.2018 - 21:34
fonte

Leggi altre domande sui tag