Collezioni, relazioni e modifiche al tracciamento (in DDD)

5

Diciamo che abbiamo un Book che ha un List di Author s. L'ordine di Author s è importante.

Abbiamo quindi la pagina di aggiornamento, in cui l'utente può 1) aggiungere un nuovo autore, 2) rimuovere l'autore esistente o 3) modificare l'ordine. Quello che ho come input è la lista dei nuovi autori.

Trovo spesso questo problema - spesso ci sono molti modelli con questo tipo di relazione. A volte l'ordine non è importante (quindi usiamo Set ) ma più-meno è come questo.

Nel mio metodo aziendale, ho bisogno di:

  • rileva il nuovo Authors , quindi posso inserirli
  • rileva rimosso Authors , quindi posso rimuoverli
  • supponiamo che tutto il resto sia aggiornato.

Non posso semplicemente riapplicare gli autori (eliminare e quindi inserire) poiché ci sono dati aggiuntivi relativi a un libro e un autore.

Fare questo manualmente ogni volta è soggetto a errori. C'è un modo migliore per tenere traccia delle modifiche nelle raccolte correlate?

Dovrei invece tenere traccia delle modifiche sull'interfaccia utente (poiché questo è il luogo in cui si verificano) e quindi fornire più input di un solo elenco di tutti gli utenti: ad esempio, l'elenco delle modifiche, l'elenco delle rimozioni? In quel caso il mio metodo di business avrebbe bisogno di più parametri, cioè liste per ogni tipo di cambiamento (rimozione, ecc.).

Infine, stavo pensando di memorizzare un insieme di eventi per aggiornamento, quindi posso ripeterli facilmente sul modello.

Devo gestire questo margine nel modello o nel mio metodo di servizio?

Qualche saggezza su questo?

    
posta lawpert 17.11.2014 - 15:31
fonte

3 risposte

4

Proverò a rispondere con le informazioni che mi hai dato.

Hai scritto

I need to:

  • detect new Authors, so I can insert them
  • detect removed Authors, so I can remove them
  • assume everything else is updated.

Quindi penso che il tuo approccio sia troppo CRUD per DDD e radici aggregate. I miei 2 centesimi il tuo metodo di business è qualcosa come Update (Book) e il parametro è il Book modificato (i suoi dati, isbn o titolo per esempio, e / o la sua collezione di autori) ed è per questo che devi "rilevare" i cambiamenti nel radice aggregata e perché sei nei guai su come farlo.

Implementerei un schema di comando e segregerò ogni caso utente in un comando.

  1. Modifica le informazioni del libro
  2. Aggiungi autore
  3. Rimuovi autore
  4. Modifica autore
  5. Modifica dell'ordine dell'autore

Ciò richiederà una buona interfaccia utente basata sull'attività design.

Quindi, puoi scegliere la strategia più adatta:

  1. Esegui immediatamente ogni comando e salva in persistenza. Ottieni Prenota radice aggregata, modifica dati libro o raccolta autori (dipende dal comando) e aggiorna la persistenza. Nessuna necessità di tenere traccia delle modifiche.

  2. Esegui istantaneamente ogni comando nella radice aggregata in memoria e attendi premendo il pulsante "Salva". Quindi vai alla persistenza. Se si archiviano i comandi eseguiti nell'aggregato fino a quando la persistenza viene aggiornata, si conosce già l'aggiornamento in persistenza. Modifiche rilevate dai comandi eseguiti nell'aggregato.

  3. Archivia un elenco di comandi generati dall'utente ed eseguirlo in un batch quando l'utente preme "Salva"; utilizzare la strategia (1) o (2) per aggiornare gli aggregati e la persistenza.

Ultime parole e suggerimenti:

Anche il design dell'interfaccia utente influisce sull'architettura e sui pattern che è possibile utilizzare. Pensa a tutto nel suo complesso.

Ogni strategia elencata sopra ha i suoi usi. Dipende dal tuo dominio, contesto, ambiente, tecnologie che usi, ecc.

Puoi usare diverse strategie. Non è necessario attenersi a uno solo in ogni contesto limitato.

Il tuo dominio deve modellare le azioni del caso utente. Non fare solo l'aggiornamento (libro). Modella ogni azione (ogni esecuzione di comando) nella sua funzione e applica le relative regole di dominio e invarianti.

    
risposta data 02.12.2014 - 12:39
fonte
3

Se gli autori sono oggetti valore, puoi ricreare facilmente l'intero elenco ogni volta perché solo il loro valore è importante, non è necessario correlarli agli oggetti identificati. Questo potrebbe essere a costo di perdere l'intento di business, dal momento che non catturi ciò che l'utente vuole esattamente fare.

Se sono Entità, suggerisco di inviare comandi granulari a Libro - AddAuthor , RemoveAuthor , ChangeAuthorOrder . Quest'ultimo dovrà includere indici di ordine distinti per tutti gli autori, altrimenti il Libro può entrare in uno stato incoerente.

    
risposta data 02.12.2014 - 12:01
fonte
2

Il modo in cui faccio questo è basato su un aggiornamento completo utilizzando una rappresentazione strutturata del record. Alcuni chiamerebbero questo un oggetto Data Transfer (DTO). Qualcosa come:

{ # book
  'id': 123,
  'title': 'The Art of Computer Programming',
  'authors': [
    {
       'id': 456,
       'name': 'Donald Knuth'
    }
  ]
}

Nell'elenco degli autori, se il record dell'autore esiste già, ottiene un ID. Se non c'è id, è un nuovo record. Gli autori eliminati semplicemente non compaiono nell'elenco.

A seconda del front-end dell'applicazione, questo viene generato in diversi modi:

  • In un'applicazione di moduli HTML tradizionale, il server decodifica i dati del modulo pubblicato
  • In un'applicazione Ajax, JSON viene generato sul client e inviato al server
  • Le app per dispositivi mobili e grassi funzionano in modo simile a un'app Ajax

Io uso sempre le librerie quindi non lo faccio a mano: la libreria la genera in base a una definizione strutturata del modulo.

Il prossimo passo è quello di convalidare il DTO e applicarlo agli oggetti del tuo dominio. Ci sono alcune sottigliezze per farlo bene. In particolare, se un autore ha già un ID, è necessario verificare che l'ID sia già associato a quel libro. In caso contrario, rischi gli attacchi violazione dei parametri .

Ancora, uso sempre le librerie per fare questo. ToscaWidgets ha un grande supporto per questo, eseguendo di nuovo tutte le convalide basate su una definizione strutturata del modulo.

Il passaggio finale consiste nel mantenere i tuoi oggetti di dominio. La maggior parte degli ORM lo fa automaticamente.

Questo modello consente di eseguire in modo affidabile aggiornamenti complessi. Mi è sempre piaciuto lo stile di grandi forme con sotto-forme, piuttosto che costringere gli utenti a fare clic su più pagine. Uso questo schema molto per forme estremamente complesse, inclusi più livelli di nidificazione, e funziona alla grande.

    
risposta data 02.12.2014 - 13:21
fonte

Leggi altre domande sui tag