Il servizio applicativo in DDD dovrebbe fare riferimento a entità non root e oggetti valore all'interno di un aggregato?

0

Comprendo che gli oggetti esterni a un aggregato non devono contenere riferimenti a entità e oggetti valore appartenenti all'aggregato. La mia domanda se questo si applica anche al servizio applicativo che espone i casi d'uso al codice cliente.

Ad esempio, se ho un ordine aggregato e Order Line è un oggetto valore all'interno dell'aggregato, quale sarebbe un approccio più consigliato:

Opzione 1: referenziazione di oggetti figlio dal servizio dell'applicazione

class OrderApplicationService
  # code ommited

  def removeOrderLine(order_id, order_line_product_id)
    order = OrdersRepository.find(order_id)
    order_line = order.find_line_by_product(order_line_product_id)

    order.remove_line(order_line)

    OrdersRepository.save(order)
  end

Opzione 2: utilizzo di valori primitivi invece di oggetti secondari

class OrderApplicationService
  # code ommited

  def removeOrderLine(order_id, order_line_product_id)
    order = OrdersRepository.find(order_id)      

    order.remove_line_by_product(order_line_product_id)

    OrdersRepository.save(order)
  end

end
    
posta FedericoG 23.06.2017 - 20:29
fonte

2 risposte

1

Questo specifico frammento dimostra un modello di dominio anemico

order_line = order.find_line_by_product(order_line_product_id)

Non c'è alcun motivo particolare per cui il servizio applicativo debba partecipare al processo aziendale. Cercando di interrogare la radice aggregata in questo modo, stai indicando il percorso sbagliato.

L'idea più importante è che il modello di dominio sia responsabile dell'interpretazione del comando; la responsabilità dell'applicazione (OrderApplicationService) è solo quella di fornire i dati corretti al modello.

Oltre a ciò, vuoi che la lingua, specialmente all'interno del modello, corrisponda alla lingua del dominio il più vicino possibile.

Quindi questa variazione è vicina ...

def removeOrderLine(order_id, order_line_product_id)
  order = OrdersRepository.find(order_id)

  order.remove_line(order_line_product_id)

  OrdersRepository.save(order)
end

Ma uno di questi potrebbe essere migliore, a seconda di come appare un ordine nel tuo dominio

"Rimuoviamo le righe da un ordine"

def removeOrderLine(order_id, line_id)
  order = OrdersRepository.find(order_id)

  order.remove_line(line_id)

  OrdersRepository.save(order)
end

"Rimuoviamo i prodotti da un ordine"

def removeOrderLine(order_id, product_id)
  order = OrdersRepository.find(order_id)

  order.remove_product(product_id)

  OrdersRepository.save(order)
end
    
risposta data 23.06.2017 - 21:06
fonte
0

Se si utilizza "order_line_product_id" che ha l'aspetto di un'identità globale, mi sembra che l'applicazione debba utilizzare OrderLine direttamente e non solo tramite il modello Order. Se definisci l'Ordine come solo un'entità e non aggrega la tua vita sarà più semplice e potresti creare un repository OrderLine e fare qualcosa del genere: OrderLineRepository.delete(order_line_product_id) .

Se vuoi ancora utilizzare la modalità aggregata piuttosto che perdere l'identità "order_line_product_id" e utilizzare qualcosa come order.remove_line(line_number) , il numero di riga è solo univoco per ordine. Quindi se vuoi rimuovere la prima riga dell'ordine (qualsiasi ordine) chiami questo order.remove_line (1) o l'ultima riga order.remove_line(order.lines_count) . In tal caso, la chiave primaria univoca nella tabella delle righe di ordine deve essere composta da due colonne order_id e line_number

    
risposta data 05.07.2017 - 00:41
fonte

Leggi altre domande sui tag