Sono abbastanza nuovo nell'implementazione di CQRS e Event Sourcing, mentre applichiamo le regole del design guidato dal dominio. Diciamo che ho un Order
aggregato e al suo interno c'è un elenco di OrderLine
entità. Sto usando questo modello nel contesto di un sistema basato su eventi (con CQRS) e quindi i cambiamenti di stato sono principalmente guidati dagli eventi. Le modifiche all'aggregato devono essere eseguite attraverso Order
poiché funge da radice aggregata. Quando, ad esempio, viene generato un evento come ItemAdded
, il rispettivo aggregato Order
verrà chiamato per applicarlo a se stesso, qualcosa come order.apply(itemAdded)
. Ciò attiverà quindi la creazione di un nuovo oggetto OrderLine
interno per rappresentare l'elemento appena aggiunto nell'ordine. In termini di implementazione, ha senso che il nuovo oggetto OrderLine
applichi direttamente l'evento a se stesso? Oppure, dovrei lasciarlo al Order
aggregato per creare l'oggetto OrderLine
attraverso un costruttore?
Quale è più appropriato?
void apply(ItemAdded itemAdded) {
OrderLine orderLine = new OrderLine();
oderLine.apply(itemAdded);
orderLines.add(orderLine);
}
o
void apply(ItemAdded itemAdded) {
OrderLine orderLine = new OrderLine(
itemAdded.getId(),
itemAdded.getProductId(),
itemAdded.getQuantity(),
itemAdded.getPrice()
);
orderLines.add(orderLine);
}
Per ora, penso che il primo approccio sia più conciso e più facile da capire. Ci sono eventi i cui campi possono essere molto lunghi e avere l'entità interna stessa che si occupa della costruzione rende il codice più pulito. Il problema, tuttavia, penso sia che, fornendo un metodo apply
nel OrderLine
, lo sto aprendo per eventuali modifiche al di fuori del contesto di Order
. Se fornisco un accessor, diciamo, getOrderLines()
, in Order
, anche se faccio in modo che la collezione / lista stessa non sia modificabile, gli oggetti contenuti saranno comunque mutabili. Un modo per prevenire ciò è restituire i cloni, ma ciò può risultare un po 'complicato da implementare per entità nidificate abbastanza complesse.
Per risolvere questo problema, quello che sto pensando è mantenere il metodo apply
in OrderLine
class, ma limitarne la visibilità. L'approccio che mi dà maggiore flessibilità in questo senso è di rendere OrderLine
una classe nidificata sotto Order
class. Ciò significa che posso mantenere il metodo apply
privato ma ancora accessibile nel contesto della classe Order
. Tuttavia, questo potrebbe significare una classe molto lunga di Order
, specialmente se ho bisogno di aggiungere altre entità nidificate in futuro.
In alternativa, posso limitare l'accesso al metodo apply
a livello di pacchetto, il che significa che devo fare qualche ristrutturazione per limitare tutte le classi di dominio in un unico pacchetto.
Qualche consiglio in merito?