Come mantenere la regola aziendale in caso di due aggregati diversi?

0

Ho un caso di modellazione del dominio: esistono due concetti di dominio Worksite e Contract. Ogni contratto appartiene ad un cantiere. Ho già scoperto che entrambi i concetti sono propri aggregati, ma esiste ancora una regola aziendale che il periodo di validità del contratto deve essere sempre compreso nel periodo di durata del cantiere. Quindi, come mantenere quella coerenza vera?

Va bene, quando creo un nuovo contratto posso farlo come segue:

public class Worksite {

   private Period period;            

   public Contract createContract( Period period, ... ) {

     if ( !this.period.inside( period ) ) ) {
       throw new SomeException();
     } 

     ...

     return new Contract( new ContractId( .. ), this.id(), period, ... );

  }    

}

ma cosa posso fare, quando qualcuno modifica il periodo di Worksites o di contratto in seguito? Entrambi hanno un limite di consistenza diverso, quindi non posso farlo nella stessa transazione .. o è questo il caso in cui ho bisogno di infrangere la regola?

    
posta Toni 23.04.2017 - 18:15
fonte

2 risposte

1

Quindi attenzione numero uno: ritagliare il modello in aggregati è un'ottimizzazione. Aggregati non rendono il modello più corretto. Quello che fanno è ridurre la quantità di stato che il modello deve prendere in considerazione in ogni cambiamento dato, e ti danno la possibilità di apportare modifiche concomitanti a bit di stato non correlati.

Every Contract belongs to some Worksite.

Ciò suggerisce che le entità del contratto e l'entità del worksite correlato potrebbero far parte dello stesso aggregato. Questa dovrebbe essere la prima strada da esplorare: qual è il costo di mantenere insieme lo stato correlato?

Seconda cosa per essere sicuri di capire: il modello è l'autorità che decide questa informazione, o è il modello che controlla solo che decisioni coerenti sono state prese altrove (o che la registrazione dei dati è stata eseguita correttamente).

Se i contratti e i periodi del cantiere sono determinati al di fuori del modello, il modello probabilmente non dovrebbe rifiutare le modifiche. Chi hai intenzione di credere, il modello o l'inchiostro sul contratto?

Greg Young ha avuto un suggerimento interessante in questo spazio: interrompi l'ingegnerizzazione . In molti casi, è possibile ottenere molto valore dal fatto che la soluzione rilevi inconsistenze e trasformarle in un essere umano, piuttosto che provare a risolverle immediatamente nel codice. Qual è il rapporto costi / benefici del lavoro extra per ottenere risultati immediatamente coerenti, piuttosto che una correzione dopo l'escalation?

D'altra parte, se il modello è davvero l'autorità per decidere dove sono i periodi, allora si vogliono sicuramente entrambi i periodi nello stesso aggregato, e dovresti esaminare il modello del dominio per assicurarti di capire veramente dove quei dati appartiene.

(Suggerimento: gli aggregati sono informazioni, non cose fisiche. Puoi esplorare l'ubiquitario linguaggio del tuo dominio per vedere se "cantiere" è il nome giusto da avere nel tuo modello, da dove viene il periodo del cantiere? da?)

    
risposta data 24.04.2017 - 20:07
fonte
0

Non dovresti infrangere la regola se è ciò di cui l'azienda ha bisogno.

Considerato che ci sono due aggregati separati, allora la consistenza finale deve entrare in gioco.

Quindi, cosa succede quando qualcuno modifica il periodo di un contratto? Dobbiamo assicurarci che il periodo sia ancora all'interno del cantiere, ma tali informazioni si trovano all'interno di un altro aggregato.

La soluzione è che, quando qualcuno cerca di modificare il periodo di un contratto, iniziamo un processo di verifica e solo dopo che il processo è terminato, in realtà cambiamo il periodo del contratto.

Facciamo ciò mettendo il aggregate in uno stato speciale chiamato per esempio period_verification_started , senza cambiare il vecchio periodo. Quindi iniziamo un Saga / Process manager che carica Worksite da repository , ottiene il suo periodo e lo inoltra a Contract aggregate . Il Contract aggregate controlla l'invariante, quindi modifica il periodo o rifiuta la richiesta di modifica impostando il suo stato di conseguenza.

D'altra parte, se una Worksite ha bisogno di cambiare il suo periodo, allora la stessa strategia potrebbe essere impiegata iniziando un Saga che carica tutto il Contracts rilevante dal repository e se l'invariante tiene solo allora periodo è "commesso".

Se viene utilizzato un Event-driven architecture tutto ciò è più semplice da parte di Sagas che ascolta il relativo events e inviando commands al due Aggregates .

    
risposta data 23.04.2017 - 19:59
fonte

Leggi altre domande sui tag