Dove va la logica aziendale che coinvolge più aggregati?

5

Sono ancora un principiante quando si tratta di design di dominio, e sto cercando di modellare qualcosa come il sistema di battaglia di un RPG come un contesto limitato. Sto provando a modellare un contesto limitato in cui un Combatant ha una lista di abilità, e ciascuna Abilità ha una lista di effetti che si applicherebbe. Ad esempio, un effetto comune sarebbe infliggere danno al Combattente bersaglio.

Per quanto posso dire, le due radici aggregate sarebbero Combatant e Ability, con Effect che è un oggetto value.

Ora, non sono sicuro di dove mettere la mia logica per l'interazione tra Combattenti. In particolare, avrò bisogno di una logica che gestisca l'esecuzione di un'abilità tenendo conto del Combattente sorgente e del Combattente bersaglio. Allo stesso modo, avrò bisogno di una logica simile per gli effetti individuali di un'abilità. Poiché l'azione e gli effetti sono causati da un'istanza di un Combattente e stanno prendendo di mira una seconda istanza di Combattente, non penso che la logica debba essere eseguita all'interno del Combatant aggregato stesso.

Il problema è che semplicemente non so dove dovrebbe andare la logica. Inizialmente pensavo che un servizio di dominio sarebbe stato il posto giusto, ma dopo averli studiati, penso che potrei essermi sbagliato. Qualcuno ha qualche idea su dove dovrei mettere questa logica?

    
posta LayfieldK 04.02.2018 - 17:16
fonte

1 risposta

5

La logica aziendale che coordina i processi che coinvolgono più Aggregati dovrebbe rimanere in un manager Saga / Process . Questo non significa che tutta la logica dovrebbe rimanere lì. No. Solo la logica di coordinamento. L'implementazione effettiva dipende dal linguaggio di programmazione e dall'architettura, ma potrei fornirti ed esempio.

Per esempio, supponiamo che un combattente infligga danno (fuoco) ad un altro combattente. Il processo di attivazione è gestito da un Saga . Ma ogni combattente dovrebbe avere due metodi di comando: inflectDamageTo e getDamagedBy . La Saga carica l'aggregazione shooter , chiama shooter.fireAt(shootedId, effect) e mantiene le modifiche. Quindi carica il shooted aggregato, chiama shooted.getDamagedBy(shooterId, effect) e mantiene le modifiche.

Prima e dopo ogni passo la Saga potrebbe persistere nei suoi progressi. Questo potrebbe essere semplice come Enum . Lo fai per avere abbastanza informazioni da recuperare in caso qualcosa vada storto e la Saga venga forzatamente interrotta (cioè il processo viene fermato, il server viene riavviato, ecc.).

Ricorda che in questo processo hai due transazioni, non solo una (o nessuna, a seconda del tipo di persistenza). Inoltre, nota che ogni aggregato riceve solo l'ID dell'altro e non un riferimento completo.

P.S. Esistono alcuni domini in cui le prestazioni sono più importanti della manutenibilità del codice o della coerenza dei dati; Baso la mia risposta sul fatto che hai analizzato i tuoi requisiti aziendali e vuoi comunque utilizzare l'approccio DDD.

    
risposta data 04.02.2018 - 18:14
fonte

Leggi altre domande sui tag